restructured repository based on following standards:

https://github.com/HW-Core/directory-structure
This commit is contained in:
Yehonal
2016-07-08 23:58:11 +02:00
parent eda1171939
commit 9fd22872c0
2536 changed files with 433 additions and 2158 deletions

View File

@@ -0,0 +1,43 @@
# Copyright (C)
#
# This file is free software; as a special exception the author gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
if( CMAKE_COMPILER_IS_GNUCXX )
add_definitions(--no-warnings)
elseif( MSVC )
add_definitions(/W0)
endif()
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
if(SERVERS AND NOT NOJEM)
add_subdirectory(jemalloc)
endif()
endif()
if(CMAKE_SYSTEM_NAME MATCHES "Windows")
add_subdirectory(acelite)
if(USE_MYSQL_SOURCES)
add_subdirectory(mysqllite)
endif()
if(TOOLS)
add_subdirectory(bzip2)
endif()
add_subdirectory(zlib)
endif()
add_subdirectory(g3dlite)
add_subdirectory(recastnavigation)
if(SERVERS)
add_subdirectory(gsoap)
endif()
if(TOOLS)
add_subdirectory(libmpq)
endif()

View File

@@ -0,0 +1,45 @@
SunwellCore uses (parts of or in whole) the following opensource software :
ACE (ADAPTIVE Communication Environment)
http://www.cs.wustl.edu/~schmidt/ACE.html
Version: 6.1.4
bzip2 (a freely available, patent free, high-quality data compressor)
http://www.bzip.org/
Version: 1.0.6
G3D (a commercial-grade C++ 3D engine available as Open Source (BSD License)
http://g3d.sourceforge.net/
Version: 8.01-Release
jemalloc (a general-purpose scalable concurrent malloc-implementation)
http://www.canonware.com/jemalloc/
Version: 3.5.1
libMPQ (a library for reading MPQ files)
https://libmpq.org/
Version: 1.0.4
MySQL (the world's most popular open source database software)
http://www.mysql.com/
Version: 5.5.9 (GA)
SFMT (SIMD-oriented Fast Mersenne Twister)
Based on http://agner.org/random/
Version: 2010-Aug-03
utf8-cpp (UTF-8 with C++ in a Portable Way)
http://utfcpp.sourceforge.net/
Version: 2.3.4
zlib (A Massively Spiffy Yet Delicately Unobtrusive Compression Library)
http://www.zlib.net/
Version: 1.2.7
gSOAP (a portable development toolkit for C and C++ XML Web services and XML data bindings)
http://gsoap2.sourceforge.net/
Version: 2.8.10
recastnavigation (Recast is state of the art navigation mesh construction toolset for games)
http://code.google.com/p/recastnavigation/
Version: 1.4

357
modules/dep/SFMT/SFMT.h Normal file
View File

@@ -0,0 +1,357 @@
/*
* Copyright notice
* ================
* GNU General Public License http://www.gnu.org/licenses/gpl.html
* This C++ implementation of SFMT contains parts of the original C code
* which was published under the following BSD license, which is therefore
* in effect in addition to the GNU General Public License.
* Copyright (c) 2006, 2007 by Mutsuo Saito, Makoto Matsumoto and Hiroshima University.
* Copyright (c) 2008 by Agner Fog.
* Copyright (c) 2008-2013 Trinity Core
*
* BSD License:
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* > Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* > Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* > Neither the name of the Hiroshima University nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SFMT_H
#define SFMT_H
#include <emmintrin.h> // Define SSE2 intrinsics
#include "randomc.h" // Define integer types etc
#include <time.h>
#include <new>
// Choose one of the possible Mersenne exponents.
// Higher values give longer cycle length and use more memory:
//#define MEXP 607
//#define MEXP 1279
//#define MEXP 2281
//#define MEXP 4253
#define MEXP 11213
//#define MEXP 19937
//#define MEXP 44497
// Define constants for the selected Mersenne exponent:
#if MEXP == 44497
#define SFMT_N 348 // Size of state vector
#define SFMT_M 330 // Position of intermediate feedback
#define SFMT_SL1 5 // Left shift of W[N-1], 32-bit words
#define SFMT_SL2 3 // Left shift of W[0], *8, 128-bit words
#define SFMT_SR1 9 // Right shift of W[M], 32-bit words
#define SFMT_SR2 3 // Right shift of W[N-2], *8, 128-bit words
#define SFMT_MASK 0xeffffffb,0xdfbebfff,0xbfbf7bef,0x9ffd7bff // AND mask
#define SFMT_PARITY 1,0,0xa3ac4000,0xecc1327a // Period certification vector
#elif MEXP == 19937
#define SFMT_N 156 // Size of state vector
#define SFMT_M 122 // Position of intermediate feedback
#define SFMT_SL1 18 // Left shift of W[N-1], 32-bit words
#define SFMT_SL2 1 // Left shift of W[0], *8, 128-bit words
#define SFMT_SR1 11 // Right shift of W[M], 32-bit words
#define SFMT_SR2 1 // Right shift of W[N-2], *8, 128-bit words
#define SFMT_MASK 0xdfffffef,0xddfecb7f,0xbffaffff,0xbffffff6 // AND mask
#define SFMT_PARITY 1,0,0,0x13c9e684 // Period certification vector
#elif MEXP == 11213
#define SFMT_N 88 // Size of state vector
#define SFMT_M 68 // Position of intermediate feedback
#define SFMT_SL1 14 // Left shift of W[N-1], 32-bit words
#define SFMT_SL2 3 // Left shift of W[0], *8, 128-bit words
#define SFMT_SR1 7 // Right shift of W[M], 32-bit words
#define SFMT_SR2 3 // Right shift of W[N-2], *8, 128-bit words
#define SFMT_MASK 0xeffff7fb,0xffffffef,0xdfdfbfff,0x7fffdbfd // AND mask
#define SFMT_PARITY 1,0,0xe8148000,0xd0c7afa3 // Period certification vector
#elif MEXP == 4253
#define SFMT_N 34 // Size of state vector
#define SFMT_M 17 // Position of intermediate feedback
#define SFMT_SL1 20 // Left shift of W[N-1], 32-bit words
#define SFMT_SL2 1 // Left shift of W[0], *8, 128-bit words
#define SFMT_SR1 7 // Right shift of W[M], 32-bit words
#define SFMT_SR2 1 // Right shift of W[N-2], *8, 128-bit words
#define SFMT_MASK 0x9f7bffff, 0x9fffff5f, 0x3efffffb, 0xfffff7bb // AND mask
#define SFMT_PARITY 0xa8000001, 0xaf5390a3, 0xb740b3f8, 0x6c11486d // Period certification vector
#elif MEXP == 2281
#define SFMT_N 18 // Size of state vector
#define SFMT_M 12 // Position of intermediate feedback
#define SFMT_SL1 19 // Left shift of W[N-1], 32-bit words
#define SFMT_SL2 1 // Left shift of W[0], *8, 128-bit words
#define SFMT_SR1 5 // Right shift of W[M], 32-bit words
#define SFMT_SR2 1 // Right shift of W[N-2], *8, 128-bit words
#define SFMT_MASK 0xbff7ffbf, 0xfdfffffe, 0xf7ffef7f, 0xf2f7cbbf // AND mask
#define SFMT_PARITY 0x00000001, 0x00000000, 0x00000000, 0x41dfa600 // Period certification vector
#elif MEXP == 1279
#define SFMT_N 10 // Size of state vector
#define SFMT_M 7 // Position of intermediate feedback
#define SFMT_SL1 14 // Left shift of W[N-1], 32-bit words
#define SFMT_SL2 3 // Left shift of W[0], *8, 128-bit words
#define SFMT_SR1 5 // Right shift of W[M], 32-bit words
#define SFMT_SR2 1 // Right shift of W[N-2], *8, 128-bit words
#define SFMT_MASK 0xf7fefffd, 0x7fefcfff, 0xaff3ef3f, 0xb5ffff7f // AND mask
#define SFMT_PARITY 0x00000001, 0x00000000, 0x00000000, 0x20000000 // Period certification vector
#elif MEXP == 607
#define SFMT_N 5 // Size of state vector
#define SFMT_M 2 // Position of intermediate feedback
#define SFMT_SL1 15 // Left shift of W[N-1], 32-bit words
#define SFMT_SL2 3 // Left shift of W[0], *8, 128-bit words
#define SFMT_SR1 13 // Right shift of W[M], 32-bit words
#define SFMT_SR2 3 // Right shift of W[N-2], *8, 128-bit words
#define SFMT_MASK 0xfdff37ff, 0xef7f3f7d, 0xff777b7d, 0x7ff7fb2f // AND mask
#define SFMT_PARITY 0x00000001, 0x00000000, 0x00000000, 0x5986f054 // Period certification vector
#endif
// Functions used by SFMTRand::RandomInitByArray (UNUSED AND COMMENTED OUT)
/*
static uint32_t func1(uint32_t x) {
return (x ^ (x >> 27)) * 1664525U;
}
static uint32_t func2(uint32_t x) {
return (x ^ (x >> 27)) * 1566083941U;
}
*/
// Subfunction for the sfmt algorithm
static inline __m128i sfmt_recursion(__m128i const &a, __m128i const &b,
__m128i const &c, __m128i const &d, __m128i const &mask) {
__m128i a1, b1, c1, d1, z1, z2;
b1 = _mm_srli_epi32(b, SFMT_SR1);
a1 = _mm_slli_si128(a, SFMT_SL2);
c1 = _mm_srli_si128(c, SFMT_SR2);
d1 = _mm_slli_epi32(d, SFMT_SL1);
b1 = _mm_and_si128(b1, mask);
z1 = _mm_xor_si128(a, a1);
z2 = _mm_xor_si128(b1, d1);
z1 = _mm_xor_si128(z1, c1);
z2 = _mm_xor_si128(z1, z2);
return z2;
}
// Class for SFMT generator
class SFMTRand { // Encapsulate random number generator
friend class ACE_TSS<SFMTRand>;
public:
SFMTRand()
{
LastInterval = 0;
RandomInit((int)(time(0)));
}
void RandomInit(int seed) // Re-seed
{
// Re-seed
uint32_t i; // Loop counter
uint32_t y = seed; // Temporary
uint32_t statesize = SFMT_N*4; // Size of state vector
// Fill state vector with random numbers from seed
((uint32_t*)state)[0] = y;
const uint32_t factor = 1812433253U;// Multiplication factor
for (i = 1; i < statesize; i++) {
y = factor * (y ^ (y >> 30)) + i;
((uint32_t*)state)[i] = y;
}
// Further initialization and period certification
Init2();
}
int32_t IRandom(int32_t min, int32_t max) // Output random integer
{
// Output random integer in the interval min <= x <= max
// Slightly inaccurate if (max-min+1) is not a power of 2
if (max <= min) {
if (max == min) return min; else return 0x80000000;
}
// Assume 64 bit integers supported. Use multiply and shift method
uint32_t interval; // Length of interval
uint64_t longran; // Random bits * interval
uint32_t iran; // Longran / 2^32
interval = (uint32_t)(max - min + 1);
longran = (uint64_t)BRandom() * interval;
iran = (uint32_t)(longran >> 32);
// Convert back to signed and return result
return (int32_t)iran + min;
}
uint32_t URandom(uint32_t min, uint32_t max)
{
// Output random integer in the interval min <= x <= max
// Slightly inaccurate if (max-min+1) is not a power of 2
if (max <= min) {
if (max == min) return min; else return 0;
}
// Assume 64 bit integers supported. Use multiply and shift method
uint32_t interval; // Length of interval
uint64_t longran; // Random bits * interval
uint32_t iran; // Longran / 2^32
interval = (uint32_t)(max - min + 1);
longran = (uint64_t)BRandom() * interval;
iran = (uint32_t)(longran >> 32);
// Convert back to signed and return result
return iran + min;
}
double Random() // Output random floating point number
{
// Output random floating point number
if (ix >= SFMT_N*4-1) {
// Make sure we have at least two 32-bit numbers
Generate();
}
uint64_t r = *(uint64_t*)((uint32_t*)state+ix);
ix += 2;
// 52 bits resolution for compatibility with assembly version:
return (int64_t)(r >> 12) * (1./(67108864.0*67108864.0));
}
uint32_t BRandom() // Output random bits
{
// Output 32 random bits
uint32_t y;
if (ix >= SFMT_N*4) {
Generate();
}
y = ((uint32_t*)state)[ix++];
return y;
}
private:
void Init2() // Various initializations and period certification
{
// Various initializations and period certification
uint32_t i, j, temp;
// Initialize mask
static const uint32_t maskinit[4] = {SFMT_MASK};
mask = _mm_loadu_si128((__m128i*)maskinit);
// Period certification
// Define period certification vector
static const uint32_t parityvec[4] = {SFMT_PARITY};
// Check if parityvec & state[0] has odd parity
temp = 0;
for (i = 0; i < 4; i++)
temp ^= parityvec[i] & ((uint32_t*)state)[i];
for (i = 16; i > 0; i >>= 1) temp ^= temp >> i;
if (!(temp & 1)) {
// parity is even. Certification failed
// Find a nonzero bit in period certification vector
for (i = 0; i < 4; i++) {
if (parityvec[i]) {
for (j = 1; j; j <<= 1) {
if (parityvec[i] & j) {
// Flip the corresponding bit in state[0] to change parity
((uint32_t*)state)[i] ^= j;
// Done. Exit i and j loops
i = 5; break;
}
}
}
}
}
// Generate first random numbers and set ix = 0
Generate();
}
void Generate() // Fill state array with new random numbers
{
// Fill state array with new random numbers
int i;
__m128i r, r1, r2;
r1 = state[SFMT_N - 2];
r2 = state[SFMT_N - 1];
for (i = 0; i < SFMT_N - SFMT_M; i++) {
r = sfmt_recursion(state[i], state[i + SFMT_M], r1, r2, mask);
state[i] = r;
r1 = r2;
r2 = r;
}
for (; i < SFMT_N; i++) {
r = sfmt_recursion(state[i], state[i + SFMT_M - SFMT_N], r1, r2, mask);
state[i] = r;
r1 = r2;
r2 = r;
}
ix = 0;
}
void* operator new(size_t size, std::nothrow_t const&)
{
return _mm_malloc(size, 16);
}
void operator delete(void* ptr, std::nothrow_t const&)
{
_mm_free(ptr);
}
void* operator new(size_t size)
{
return _mm_malloc(size, 16);
}
void operator delete(void* ptr)
{
_mm_free(ptr);
}
void* operator new[](size_t size, std::nothrow_t const&)
{
return _mm_malloc(size, 16);
}
void operator delete[](void* ptr, std::nothrow_t const&)
{
_mm_free(ptr);
}
void* operator new[](size_t size)
{
return _mm_malloc(size, 16);
}
void operator delete[](void* ptr)
{
_mm_free(ptr);
}
__m128i mask; // AND mask
__m128i state[SFMT_N]; // State vector for SFMT generator
uint32_t ix; // Index into state array
uint32_t LastInterval; // Last interval length for IRandom
uint32_t RLimit; // Rejection limit used by IRandom
};
#endif // SFMT_H

View File

@@ -0,0 +1,65 @@
/*
* Copyright notice
* ================
* GNU General Public License http://www.gnu.org/licenses/gpl.html
* This C++ implementation of SFMT contains parts of the original C code
* which was published under the following BSD license, which is therefore
* in effect in addition to the GNU General Public License.
* Copyright (c) 2006, 2007 by Mutsuo Saito, Makoto Matsumoto and Hiroshima University.
* Copyright (c) 2008 by Agner Fog.
* Copyright (c) 2008-2013 Trinity Core
*
* BSD License:
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* > Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* > Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* > Neither the name of the Hiroshima University nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef RANDOMC_H
#define RANDOMC_H
// Define integer types with known size: int32_t, uint32_t, int64_t, uint64_t.
// If this doesn't work then insert compiler-specific definitions here:
#if defined(__GNUC__)
// Compilers supporting C99 or C++0x have inttypes.h defining these integer types
#include <inttypes.h>
#define INT64_SUPPORTED // Remove this if the compiler doesn't support 64-bit integers
#elif defined(_WIN16) || defined(__MSDOS__) || defined(_MSDOS)
// 16 bit systems use long int for 32 bit integer
typedef signed long int int32_t;
typedef unsigned long int uint32_t;
#elif defined(_MSC_VER)
// Microsoft have their own definition
typedef signed __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
#define INT64_SUPPORTED // Remove this if the compiler doesn't support 64-bit integers
#else
// This works with most compilers
typedef signed int int32_t;
typedef unsigned int uint32_t;
typedef long long int64_t;
typedef unsigned long long uint64_t;
#define INT64_SUPPORTED // Remove this if the compiler doesn't support 64-bit integers
#endif
#endif // RANDOMC_H

View File

@@ -0,0 +1,13 @@
Douglas C. Schmidt
d.schmidt@vanderbilt.edu
Professor of Computer Science
Associate Chair of Computer Science and Engineering
Department of Electrical Engineering and Computer Science
Senior Researcher at the Institute for Software Integrated Systems (ISIS)
Vanderbilt University
Nashville, TN 37203
www.dre.vanderbilt.edu/~schmidt
TEL: (615) 343-8197
FAX: (615) 343-7440

View File

@@ -0,0 +1,11 @@
# Copyright (C)
#
# This file is free software; as a special exception the author gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
add_subdirectory(ace)

111
modules/dep/acelite/COPYING Normal file
View File

@@ -0,0 +1,111 @@
_________________________________________________________________
Copyright and Licensing Information for ACE(TM), TAO(TM), CIAO(TM),
DAnCE(TM), and CoSMIC(TM)
[1]ACE(TM), [2]TAO(TM), [3]CIAO(TM), DAnCE(TM), and [4]CoSMIC(TM)
(henceforth referred to as "DOC software") are copyrighted by
[5]Douglas C. Schmidt and his [6]research group at [7]Washington
University, [8]University of California, Irvine, and [9]Vanderbilt
University, Copyright (c) 1993-2015, all rights reserved. Since DOC
software is open-source, freely available software, you are free to
use, modify, copy, and distribute--perpetually and irrevocably--the
DOC software source code and object code produced from the source, as
well as copy and distribute modified versions of this software. You
must, however, include this copyright statement along with any code
built using DOC software that you release. No copyright statement
needs to be provided if you just ship binary executables of your
software products.
You can use DOC software in commercial and/or binary software releases
and are under no obligation to redistribute any of your source code
that is built using DOC software. Note, however, that you may not
misappropriate the DOC software code, such as copyrighting it yourself
or claiming authorship of the DOC software code, in a way that will
prevent DOC software from being distributed freely using an
open-source development model. You needn't inform anyone that you're
using DOC software in your software, though we encourage you to let
[10]us know so we can promote your project in the [11]DOC software
success stories.
The [12]ACE, [13]TAO, [14]CIAO, [15]DAnCE, and [16]CoSMIC web sites
are maintained by the [17]DOC Group at the [18]Institute for Software
Integrated Systems (ISIS) and the [19]Center for Distributed Object
Computing of Washington University, St. Louis for the development of
open-source software as part of the open-source software community.
Submissions are provided by the submitter ``as is'' with no warranties
whatsoever, including any warranty of merchantability, noninfringement
of third party intellectual property, or fitness for any particular
purpose. In no event shall the submitter be liable for any direct,
indirect, special, exemplary, punitive, or consequential damages,
including without limitation, lost profits, even if advised of the
possibility of such damages. Likewise, DOC software is provided as is
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. Washington University, UC Irvine, Vanderbilt University,
their employees, and students shall have no liability with respect to
the infringement of copyrights, trade secrets or any patents by DOC
software or any part thereof. Moreover, in no event will Washington
University, UC Irvine, or Vanderbilt University, their employees, or
students be liable for any lost revenue or profits or other special,
indirect and consequential damages.
DOC software is provided with no support and without any obligation on
the part of Washington University, UC Irvine, Vanderbilt University,
their employees, or students to assist in its use, correction,
modification, or enhancement. A [20]number of companies around the
world provide commercial support for DOC software, however. DOC
software is Y2K-compliant, as long as the underlying OS platform is
Y2K-compliant. Likewise, DOC software is compliant with the new US
daylight savings rule passed by Congress as "The Energy Policy Act of
2005," which established new daylight savings times (DST) rules for
the United States that expand DST as of March 2007. Since DOC software
obtains time/date and calendaring information from operating systems
users will not be affected by the new DST rules as long as they
upgrade their operating systems accordingly.
The names ACE(TM), TAO(TM), CIAO(TM), DAnCE(TM), CoSMIC(TM),
Washington University, UC Irvine, and Vanderbilt University, may not
be used to endorse or promote products or services derived from this
source without express written permission from Washington University,
UC Irvine, or Vanderbilt University. This license grants no permission
to call products or services derived from this source ACE(TM),
TAO(TM), CIAO(TM), DAnCE(TM), or CoSMIC(TM), nor does it grant
permission for the name Washington University, UC Irvine, or
Vanderbilt University to appear in their names.
If you have any suggestions, additions, comments, or questions, please
let [21]me know.
[22]Douglas C. Schmidt
_________________________________________________________________
Back to the [23]ACE home page.
References
1. http://www.cs.wustl.edu/~schmidt/ACE.html
2. http://www.cs.wustl.edu/~schmidt/TAO.html
3. http://www.dre.vanderbilt.edu/CIAO/
4. http://www.dre.vanderbilt.edu/cosmic/
5. http://www.dre.vanderbilt.edu/~schmidt/
6. http://www.cs.wustl.edu/~schmidt/ACE-members.html
7. http://www.wustl.edu/
8. http://www.uci.edu/
9. http://www.vanderbilt.edu/
10. mailto:doc_group@cs.wustl.edu
11. http://www.cs.wustl.edu/~schmidt/ACE-users.html
12. http://www.cs.wustl.edu/~schmidt/ACE.html
13. http://www.cs.wustl.edu/~schmidt/TAO.html
14. http://www.dre.vanderbilt.edu/CIAO/
15. http://www.dre.vanderbilt.edu/~schmidt/DOC_ROOT/DAnCE/
16. http://www.dre.vanderbilt.edu/cosmic/
17. http://www.dre.vanderbilt.edu/
18. http://www.isis.vanderbilt.edu/
19. http://www.cs.wustl.edu/~schmidt/doc-center.html
20. http://www.cs.wustl.edu/~schmidt/commercial-support.html
21. mailto:d.schmidt@vanderbilt.edu
22. http://www.dre.vanderbilt.edu/~schmidt/
23. http://www.cs.wustl.edu/ACE.html

2090
modules/dep/acelite/NEWS Normal file

File diff suppressed because it is too large Load Diff

222
modules/dep/acelite/README Normal file
View File

@@ -0,0 +1,222 @@
This document is also available at the following URL:
http://www.dre.vanderbilt.edu/~schmidt/ACE.html
All software and documentation is available via both anonymous ftp and
the http.]
THE ADAPTIVE COMMUNICATION ENVIRONMENT (ACE)
An Object-Oriented Network Programming Toolkit
----------------------------------------
Overview of ACE
The ADAPTIVE Communication Environment (ACE) is an object-oriented
(OO) toolkit that implements fundamental design patterns for
communication software. ACE provides a rich set of reusable C++
wrappers and frameworks that perform common communication software
tasks across a range of OS platforms, including Win32/Win64, most
versions of UNIX (e.g., SunOS, HP-UX , AIX, Linux, NetBSD, and FreeBSD),
real-time operating systems (e.g., VxWorks, Chorus, LynxOS, and QNX),
OpenVMS, and MVS OpenEdition. A single source tree is used for all
these platforms and porting ACE to other platforms is relatively easy.
The communication software components provided by ACE include event
demultiplexing and event handler dispatching, service initialization,
interprocess communication, shared memory management, message routing,
dynamic (re)configuration of distributed services, multi-threading,
and concurrency control. There are both C++ and Java versions of ACE
available.
ACE is targeted for developers of high-performance and real-time
communication services and applications on UNIX, POSIX, and Win32
platforms. ACE simplifies the development of OO network applications
and services that utilize interprocess communication, event
demultiplexing, explicit dynamic linking, and concurrency. ACE
automates system configuration and reconfiguration by dynamically
linking services into applications at run-time and executing these
services in one or more processes or threads.
ACE is currently used in commercial projects and products by dozens of
companies including Ericsson, Bellcore, Siemens, Motorola, Kodak,
Boeing, Lucent, DEC, Lockheed Martin, and SAIC. Commercial support
for ACE is available from several companies as listed at
http://www.cs.wustl.edu/~schmidt/commercial-support.html
----------------------------------------
C++ Wrappers for OS Interfaces
The lower-level portions of ACE provide a set of portable and
type-secure C++ wrappers that encapsulate the following C language OS
interfaces:
. IPC mechanisms
-- e.g., Internet- and UNIX-domain sockets, TLI, Named
Pipes (for UNIX and Win32) and STREAM pipes;
. Event demultiplexing
-- e.g., select(), poll(), and Win32
WaitForMultipleObjects and I/O completion ports;
. Multi-threading and synchronization
-- e.g., Solaris threads, POSIX Pthreads, and Win32
threads;
. Explicit dynamic linking
-- e.g., dlopen/dlsym on UNIX and LoadLibrary/GetProc
on Win32;
. Memory-mapped files and shared memory management
-- e.g., BSD mmap(), SYSV shared memory, and Win32
shared memory;
. System V IPC
-- e.g., shared memory, semaphores, message queues.
The OS Adaptation Layer shields the upper levels of ACE from platform
dependencies associated with the underlying OS interfaces.
----------------------------------------
Frameworks and Class Categories
ACE also contains a higher-level network programming framework that
integrates and enhances the lower-level C++ wrappers. This framework
supports the dynamic configuration of concurrent distributed services
into applications. The framework portion of ACE contains the
following class categories:
. The Reactor
-- Supports both Reactive and Proactive I/O;
. The Service Configurator
-- Support dynamic (re)configuration of objects;
. The ADAPTIVE Service Executive
-- A user-level implementation of System V STREAMS,
that supports modular integration of
hierarchically-related communicaion services;
. Concurrency
-- Various types of higher-level concurrency
control and synchronization patterns (such as
Polymorphic Futures and Active Objects);
. Shared Malloc
-- Components for managing dynamically allocation
of shared and local memory;
----------------------------------------
Distributed Services and Components
Finally, ACE provides a standard library of distributed services that
are packaged as components. These service components play two roles
in ACE:
1. They provide reusable components for common distributed
system tasks such as logging, naming, locking, and time
synchronization.
2. They illustrate how to utilize ACE features such as the
Reactor, Service Configurator, Service Initialization,
Concurrency, and IPC components.
----------------------------------------
Middleware Applications
ACE has been used in research and development projects at many
universities and companies. For instance, it has been used to build
avionics systems at Boeing, telecommunication systems at Bellcore,
Ericsson, Motorola, and Lucent; medical imaging systems at Siemens and
Kodak; and many academic research projects. Two example middleware
applications provided with the ACE release include:
1. The ACE ORB (TAO) -- TAO is a real-time implementation of
CORBA built using the framework components and patterns
provided by ACE.
2. JAWS -- JAWS is a high-performance, adaptive Web server
built using the components in ACE.
----------------------------------------
OBTAINING ACE
ACE may be obtained electronically from
http://download.dre.vanderbilt.edu. This release contains the source
code, test drivers, and example applications (including JAWS) for C++
wrapper libraries and the higher-level ACE network programming
framework developed as part of the ADAPTIVE project at the University
of California, Irvine, Washington University, St. Louis, and
Vanderbilt University.
You can get The ACE ORB (TAO) in a companion release at the same URL.
----------------------------------------
ACE DOCUMENTATION AND TUTORIALS
Many of the C++ wrappers and higher-level components have been
described in issues of the C++ Report, as well as in proceedings of
many journals, conferences, and workshops.
A collection of white papers and tutorial handouts are included at
http://www.dre.vanderbilt.edu/~schmidt/ACE-papers.html
This page contains PDF versions of various papers that describe
different aspects of ACE.
This material is also available available via the WWW at URL:
http://www.dre.vanderbilt.edu/~schmidt/ACE.html
----------------------------------------
ACE MAILING LIST AND NEWSGROUP
A mailing list, ace-users@list.isis.vanderbilt.edu, is available for
discussing bug fixes, enhancements, and porting issues regarding ACE.
Please send mail to me at the
ace-users-request@list.isis.vanderbilt.edu if you'd like to join the
mailing list. There is also a USENET newsgroup called
comp.soft-sys.ace. Please see
http://www.dre.vanderbilt.edu/~schmidt/ACE-mail.html for details on
how to subscribe to the mailing list.
----------------------------------------
BUILDING AND INSTALLING ACE
Please refer to the
http://www.dre.vanderbilt.edu/~schmidt/ACE-install.html file for
information on how to build and test the ACE wrappers. The
BIBLIOGRAPHY file contains information on where to obtain articles
that describe the ACE wrappers and the ADAPTIVE system in more detail.
The current release has been tested extensively, but if you find any
bugs, please report them to the ACE mailing list
ace-users@list.isis.vanderbilt.edu using the
$ACE_ROOT/PROBLEM-REPORT-FORM. Please use the same form to submit
questions, comments, etc. To ensure that you see responses, please do
one of the following:
1) Subscribe to the ace-users mail list, by sending email with
contents "subscribe ace-users" to
ace-users-request@list.isis.vanderbilt.edu.
2) Or, monitor the comp.soft-sys.ace newsgroup for responses.
----------------------------------------
ACKNOWLEDGEMENTS
Please see the file `$ACE_ROOT/THANKS' for a list of the thousands of
people who've contributed to ACE and TAO over the years.

2424
modules/dep/acelite/THANKS Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,8 @@
This is ACE version 6.3.2, released Thu May 07 10:14:44 CEST 2015
If you have any problems with or questions about ACE, please send
e-mail to the ACE mailing list (ace-bugs@list.isis.vanderbilt.edu),
using the form found in the file PROBLEM-REPORT-FORM. In order
to post to the list you must subscribe to it.
See http://www.dre.vanderbilt.edu/~schmidt/ACE-mail.html

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,884 @@
// -*- C++ -*-
//=============================================================================
/**
* @file ACE.h
*
* This file contains value added ACE functions that extend the
* behavior of the UNIX and Win32 OS calls.
*
* All these ACE static functions are consolidated in a single place
* in order to manage the namespace better. These functions are put
* here rather than in @c ACE_OS in order to separate concerns.
*
* @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
*/
//=============================================================================
#ifndef ACE_ACE_H
#define ACE_ACE_H
#include /**/ "ace/pre.h"
#include /**/ "ace/config-lite.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "ace/Basic_Types.h"
#include "ace/Default_Constants.h"
#if defined (ACE_EXPORT_MACRO)
# undef ACE_EXPORT_MACRO
#endif
#define ACE_EXPORT_MACRO ACE_Export
// Open versioned namespace, if enabled by the user.
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
// Forward declarations.
class ACE_Time_Value;
class ACE_Message_Block;
class ACE_Handle_Set;
/**
* @namespace ACE
*
* @brief The namespace containing the ACE framework itself.
*
* The ACE namespace contains all types (classes, structures,
* typedefs, etc), and global functions and variables in the ACE
* framework.
*/
namespace ACE
{
// = ACE version information.
/// e.g., the "5" in ACE 5.1.12.
extern ACE_Export u_int major_version (void);
/// e.g., the "1" in ACE 5.1.12.
extern ACE_Export u_int minor_version (void);
/// e.g., the "12" in ACE 5.1.12.
/// Returns 0 for "stable" (non-beta) releases.
extern ACE_Export u_int beta_version (void);
// = C++ compiler version information.
/// E.g., the "SunPro C++" in SunPro C++ 4.32.0
extern ACE_Export const ACE_TCHAR * compiler_name (void);
/// E.g., the "4" in SunPro C++ 4.32.0
extern ACE_Export u_int compiler_major_version (void);
/// E.g., the "32" in SunPro C++ 4.32.0
extern ACE_Export u_int compiler_minor_version (void);
/// E.g., the "0" in SunPro C++ 4.32.0
extern ACE_Export u_int compiler_beta_version (void);
/// Check if error indicates the process being out of handles (file
/// descriptors).
extern ACE_Export int out_of_handles (int error);
/// Simple wildcard matching function supporting '*' and '?'
/// return true if string s matches pattern.
/// If @a character_classes is true, '[' is treated as a wildcard character
/// as described in the fnmatch() POSIX API. The following POSIX "bracket
/// expression" features are not implemented: collating symbols, equivalence
/// class expressions, and character class expressions. The POSIX locale is
/// assumed.
extern ACE_Export bool wild_match(const char* s, const char* pattern,
bool case_sensitive = true, bool character_classes = false);
/**
* @name I/O operations
*
* Notes on common parameters:
*
* @a handle is the connected endpoint that will be used for I/O.
*
* @a buf is the buffer to write from or receive into.
*
* @a len is the number of bytes to transfer.
*
* The @a timeout parameter in the following methods indicates how
* long to blocking trying to transfer data. If @a timeout == 0,
* then the call behaves as a normal send/recv call, i.e., for
* blocking sockets, the call will block until action is possible;
* for non-blocking sockets, @c EWOULDBLOCK will be returned if no
* action is immediately possible.
*
* If @a timeout != 0, the call will wait until the relative time
* specified in @a *timeout elapses.
*
* The "_n()" I/O methods keep looping until all the data has been
* transferred. These methods also work for sockets in non-blocking
* mode i.e., they keep looping on @c EWOULDBLOCK. @a timeout is
* used to make sure we keep making progress, i.e., the same timeout
* value is used for every I/O operation in the loop and the timeout
* is not counted down.
*
* The return values for the "*_n()" methods match the return values
* from the non "_n()" methods and are specified as follows:
*
* - On complete transfer, the number of bytes transferred is returned.
* - On timeout, -1 is returned, @c errno == @c ETIME.
* - On error, -1 is returned, @c errno is set to appropriate error.
* - On @c EOF, 0 is returned, @c errno is irrelevant.
*
* On partial transfers, i.e., if any data is transferred before
* timeout / error / @c EOF, @a bytes_transferred> will contain the
* number of bytes transferred.
*
* Methods with @a iovec parameter are I/O vector variants of the
* I/O operations.
*
* Methods with the extra @a flags argument will always result in
* @c send getting called. Methods without the extra @a flags
* argument will result in @c send getting called on Win32
* platforms, and @c write getting called on non-Win32 platforms.
*/
//@{
extern ACE_Export ssize_t recv (ACE_HANDLE handle,
void *buf,
size_t len,
int flags,
const ACE_Time_Value *timeout = 0);
#if defined (ACE_HAS_TLI)
extern ACE_Export ssize_t t_rcv (ACE_HANDLE handle,
void *buf,
size_t len,
int *flags,
const ACE_Time_Value *timeout = 0);
#endif /* ACE_HAS_TLI */
extern ACE_Export ssize_t recv (ACE_HANDLE handle,
void *buf,
size_t len,
const ACE_Time_Value *timeout = 0);
extern ACE_Export ssize_t recvmsg (ACE_HANDLE handle,
struct msghdr *msg,
int flags,
const ACE_Time_Value *timeout = 0);
extern ACE_Export ssize_t recvfrom (ACE_HANDLE handle,
char *buf,
int len,
int flags,
struct sockaddr *addr,
int *addrlen,
const ACE_Time_Value *timeout = 0);
ACE_NAMESPACE_INLINE_FUNCTION
ssize_t recv_n (ACE_HANDLE handle,
void *buf,
size_t len,
int flags,
const ACE_Time_Value *timeout = 0,
size_t *bytes_transferred = 0);
#if defined (ACE_HAS_TLI)
ACE_NAMESPACE_INLINE_FUNCTION
ssize_t t_rcv_n (ACE_HANDLE handle,
void *buf,
size_t len,
int *flags,
const ACE_Time_Value *timeout = 0,
size_t *bytes_transferred = 0);
#endif /* ACE_HAS_TLI */
ACE_NAMESPACE_INLINE_FUNCTION
ssize_t recv_n (ACE_HANDLE handle,
void *buf,
size_t len,
const ACE_Time_Value *timeout = 0,
size_t *bytes_transferred = 0);
/// Receive into a variable number of pieces.
/**
* Accepts a variable, caller-specified, number of pointer/length
* pairs. Arguments following @a n are char *, size_t pairs.
*
* @param handle The I/O handle to receive on
* @param n The total number of char *, size_t pairs following @a n.
*
* @return -1 on error, else total number of bytes received.
*/
extern ACE_Export ssize_t recv (ACE_HANDLE handle, size_t n, ...);
extern ACE_Export ssize_t recvv (ACE_HANDLE handle,
iovec *iov,
int iovcnt,
const ACE_Time_Value *timeout = 0);
ACE_NAMESPACE_INLINE_FUNCTION
ssize_t recvv_n (ACE_HANDLE handle,
iovec *iov,
int iovcnt,
const ACE_Time_Value *timeout = 0,
size_t *bytes_transferred = 0);
extern ACE_Export ssize_t recv_n (ACE_HANDLE handle,
ACE_Message_Block *message_block,
const ACE_Time_Value *timeout = 0,
size_t *bytes_transferred = 0);
extern ACE_Export ssize_t send (ACE_HANDLE handle,
const void *buf,
size_t len,
int flags,
const ACE_Time_Value *timeout = 0);
#if defined (ACE_HAS_TLI)
extern ACE_Export ssize_t t_snd (ACE_HANDLE handle,
const void *buf,
size_t len,
int flags,
const ACE_Time_Value *timeout = 0);
#endif /* ACE_HAS_TLI */
extern ACE_Export ssize_t send (ACE_HANDLE handle,
const void *buf,
size_t len,
const ACE_Time_Value *timeout = 0);
extern ACE_Export ssize_t sendmsg (ACE_HANDLE handle,
const struct msghdr *msg,
int flags,
const ACE_Time_Value *timeout = 0);
extern ACE_Export ssize_t sendto (ACE_HANDLE handle,
const char *buf,
int len,
int flags,
const struct sockaddr *addr,
int addrlen,
const ACE_Time_Value *timeout = 0);
ACE_NAMESPACE_INLINE_FUNCTION
ssize_t send_n (ACE_HANDLE handle,
const void *buf,
size_t len,
int flags,
const ACE_Time_Value *timeout = 0,
size_t *bytes_transferred = 0);
#if defined (ACE_HAS_TLI)
ACE_NAMESPACE_INLINE_FUNCTION
ssize_t t_snd_n (ACE_HANDLE handle,
const void *buf,
size_t len,
int flags,
const ACE_Time_Value *timeout = 0,
size_t *bytes_transferred = 0);
#endif /* ACE_HAS_TLI */
ACE_NAMESPACE_INLINE_FUNCTION
ssize_t send_n (ACE_HANDLE handle,
const void *buf,
size_t len,
const ACE_Time_Value *timeout = 0,
size_t *bytes_transferred = 0);
/// Varargs variant.
extern ACE_Export ssize_t send (ACE_HANDLE handle, size_t n, ...);
extern ACE_Export ssize_t sendv (ACE_HANDLE handle,
const iovec *iov,
int iovcnt,
const ACE_Time_Value *timeout = 0);
ACE_NAMESPACE_INLINE_FUNCTION
ssize_t sendv_n (ACE_HANDLE handle,
const iovec *iov,
int iovcnt,
const ACE_Time_Value *timeout = 0,
size_t *bytes_transferred = 0);
/// Send all the @a message_blocks chained through their @c next and
/// @c cont pointers. This call uses the underlying OS gather-write
/// operation to reduce the domain-crossing penalty.
extern ACE_Export ssize_t send_n (ACE_HANDLE handle,
const ACE_Message_Block *message_block,
const ACE_Time_Value *timeout = 0,
size_t *bytes_transferred = 0);
// = File system I/O functions (these don't support timeouts).
ACE_NAMESPACE_INLINE_FUNCTION
ssize_t read_n (ACE_HANDLE handle,
void *buf,
size_t len,
size_t *bytes_transferred = 0);
ACE_NAMESPACE_INLINE_FUNCTION
ssize_t write_n (ACE_HANDLE handle,
const void *buf,
size_t len,
size_t *bytes_transferred = 0);
/// Write all the @a message_blocks chained through their @c next
/// and @c cont pointers. This call uses the underlying OS
/// gather-write operation to reduce the domain-crossing penalty.
extern ACE_Export ssize_t write_n (ACE_HANDLE handle,
const ACE_Message_Block *message_block,
size_t *bytes_transferred = 0);
extern ACE_Export ssize_t readv_n (ACE_HANDLE handle,
iovec *iov,
int iovcnt,
size_t *bytes_transferred = 0);
extern ACE_Export ssize_t writev_n (ACE_HANDLE handle,
const iovec *iov,
int iovcnt,
size_t *bytes_transferred = 0);
//@}
/**
* Wait up to @a timeout amount of time to passively establish a
* connection. This method doesn't perform the @c accept, it just
* does the timed wait.
*/
extern ACE_Export int handle_timed_accept (ACE_HANDLE listener,
ACE_Time_Value *timeout,
bool restart);
/**
* Wait up to @a timeout amount of time to complete an actively
* established non-blocking connection. If @a is_tli is non-0 then
* we are being called by a TLI wrapper (which behaves slightly
* differently from a socket wrapper).
*/
extern ACE_Export ACE_HANDLE handle_timed_complete (
ACE_HANDLE listener,
const ACE_Time_Value *timeout,
int is_tli = 0);
/**
* Reset the limit on the number of open handles. If @a new_limit
* == -1 set the limit to the maximum allowable. Otherwise, set
* the limit value to @a new_limit. If @a increase_limit_only is
* non-0 then only allow increases to the limit.
*/
extern ACE_Export int set_handle_limit (int new_limit = -1,
int increase_limit_only = 0);
/**
* Returns the maximum number of open handles currently permitted in
* this process. This maximum may be extended using
* @c ACE::set_handle_limit.
*/
extern ACE_Export int max_handles (void);
// = String functions
/**
* Return a dynamically allocated duplicate of @a str, substituting
* the environment variable if @c str[0] @c == @c '$'. Note that
* the pointer is allocated with @c ACE_OS::malloc and must be freed
* by @c ACE_OS::free.
*/
extern ACE_Export ACE_TCHAR *strenvdup (const ACE_TCHAR *str);
/// Returns a pointer to the "end" of the string, i.e., the character
/// past the '\0'.
extern ACE_Export const char *strend (const char *s);
/// This method is just like @c strdup, except that it uses
/// @c operator @c new rather than @c malloc. If @a s is NULL
/// returns NULL rather than segfaulting.
extern ACE_Export char *strnew (const char *s);
/// Delete the memory allocated by @c strnew.
ACE_NAMESPACE_INLINE_FUNCTION void strdelete (char *s);
/// Create a fresh new copy of @a str, up to @a n chars long. Uses
/// @c ACE_OS::malloc to allocate the new string.
extern ACE_Export char *strndup (const char *str, size_t n);
/// Create a fresh new copy of @a str, up to @a n chars long. Uses
/// @c ACE_OS::malloc to allocate the new string.
extern ACE_Export char *strnnew (const char *str, size_t n);
/// Determine if a specified pathname is "dot dir" (ie. "." or "..").
ACE_NAMESPACE_INLINE_FUNCTION bool isdotdir (const char *s);
#if defined (ACE_HAS_WCHAR)
extern ACE_Export const wchar_t *strend (const wchar_t *s);
extern ACE_Export wchar_t *strnew (const wchar_t *s);
ACE_NAMESPACE_INLINE_FUNCTION void strdelete (wchar_t *s);
extern ACE_Export wchar_t *strndup (const wchar_t *str, size_t n);
extern ACE_Export wchar_t *strnnew (const wchar_t *str, size_t n);
ACE_NAMESPACE_INLINE_FUNCTION bool isdotdir (const wchar_t *s);
#endif /* ACE_HAS_WCHAR */
/**
* On Windows, determines if a specified pathname ends with ".exe"
* (not case sensitive). If on Windows and there is no ".exe" suffix,
* a new ACE_TCHAR array is allocated and a copy of @c pathname with
* the ".exe" suffix is copied into it. In this case, the caller is
* responsible for calling delete [] on the returned pointer.
*
* @param pathname The name to check for a proper suffix.
*
* @retval @c pathname if there is a proper suffix for Windows. This is
* always the return value for non-Windows platforms.
* @retval If a suffix needs to be added, returns a pointer to new[]
* allocated memory containing the original @c pathname plus
* a ".exe" suffix. The caller is responsible for freeing the
* memory using delete [].
*/
extern ACE_Export const ACE_TCHAR *execname (const ACE_TCHAR *pathname);
/**
* Returns the "basename" of a @a pathname separated by @a delim.
* For instance, the basename of "/tmp/foo.cpp" is "foo.cpp" when
* @a delim is @a '/'.
*/
extern ACE_Export const ACE_TCHAR *basename (const ACE_TCHAR *pathname,
ACE_TCHAR delim =
ACE_DIRECTORY_SEPARATOR_CHAR);
/**
* Returns the "dirname" of a @a pathname. For instance, the
* dirname of "/tmp/foo.cpp" is "/tmp" when @a delim is @a '/'. If
* @a pathname has no @a delim ".\0" is returned. This method does
* not modify @a pathname and is not reentrant.
*/
extern ACE_Export const ACE_TCHAR *dirname (const ACE_TCHAR *pathname,
ACE_TCHAR delim =
ACE_DIRECTORY_SEPARATOR_CHAR);
/**
* Translate the given timestamp to ISO-8601 format.
*
* @param time_value ACE_Time_Value to format. This is assumed to be
* an absolute time value.
* @param date_and_time Array to hold the timestamp.
* @param time_len Size of @a date_and_time in ACE_TCHARs.
* Must be greater than or equal to 27.
* @param return_pointer_to_first_digit If true, returned pointer value
* is to the first time digit, else to the space
* prior to the first time digit. See Return Values.
*
* @retval 0 if unsuccessful, with errno set. If @a time_len is less than
* 27 errno will be EINVAL.
* @retval If successful, pointer to beginning of the "time" portion of
* @a date_and_time. If @a return_pointer_to_first_digit is false
* the pointer is actually to the space before the time, else
* the pointer is to the first time digit.
*/
extern ACE_Export ACE_TCHAR *timestamp (const ACE_Time_Value& time_value,
ACE_TCHAR date_and_time[],
size_t time_len,
bool return_pointer_to_first_digit = false);
/**
* Translate the current time to ISO-8601 timestamp format.
*
* @param date_and_time Array to hold the timestamp.
* @param time_len Size of @a date_and_time in ACE_TCHARs.
* Must be greater than or equal to 27.
* @param return_pointer_to_first_digit If true, returned pointer value
* is to the first time digit, else to the space
* prior to the first time digit. See Return Values.
*
* @retval 0 if unsuccessful, with errno set. If @a time_len is less than
* 27 errno will be EINVAL.
* @retval If successful, pointer to beginning of the "time" portion of
* @a date_and_time. If @a return_pointer_to_first_digit is false
* the pointer is actually to the space before the time, else
* the pointer is to the first time digit.
*/
extern ACE_Export ACE_TCHAR *timestamp (ACE_TCHAR date_and_time[],
size_t time_len,
bool return_pointer_to_first_digit = false);
/**
* if @a avoid_zombies == 0 call @c ACE_OS::fork directly, else
* create an orphan process that's inherited by the init process;
* init cleans up when the orphan process terminates so we don't
* create zombies. Returns -1 on failure and either the child PID
* on success if @a avoid_zombies == 0 or 1 on success if @a
* avoid_zombies != 0 (this latter behavior is a known bug that
* needs to be fixed).
*/
extern ACE_Export pid_t fork (
const ACE_TCHAR *program_name = ACE_TEXT ("<unknown>"),
int avoid_zombies = 0);
/**
* Become a daemon process using the algorithm in Richard Stevens
* "Advanced Programming in the UNIX Environment." If
* @a close_all_handles is non-zero then all open file handles are
* closed.
*/
extern ACE_Export int daemonize (
const ACE_TCHAR pathname[] = ACE_TEXT ("/"),
bool close_all_handles = ACE_DEFAULT_CLOSE_ALL_HANDLES,
const ACE_TCHAR program_name[] = ACE_TEXT ("<unknown>"));
// = Miscellaneous functions.
/// Rounds the request to a multiple of the page size.
extern ACE_Export size_t round_to_pagesize (size_t len);
/// Rounds the request to a multiple of the allocation granularity.
extern ACE_Export size_t round_to_allocation_granularity (size_t len);
// @@ UNICODE what about buffer?
/// Format buffer into printable format. This is useful for
/// debugging.
extern ACE_Export size_t format_hexdump (const char *buffer, size_t size,
ACE_TCHAR *obuf, size_t obuf_sz);
/// Computes the hash value of {str} using the "Hash PJW" routine.
extern ACE_Export u_long hash_pjw (const char *str);
/// Computes the hash value of {str} using the "Hash PJW" routine.
extern ACE_Export u_long hash_pjw (const char *str, size_t len);
#if defined (ACE_HAS_WCHAR)
/// Computes the hash value of {str} using the "Hash PJW" routine.
extern ACE_Export u_long hash_pjw (const wchar_t *str);
/// Computes the hash value of {str} using the "Hash PJW" routine.
extern ACE_Export u_long hash_pjw (const wchar_t *str, size_t len);
#endif /* ACE_HAS_WCHAR */
/// Computes CRC-CCITT for the string.
extern ACE_Export ACE_UINT16 crc_ccitt(const char *str);
/// Computes CRC-CCITT for the buffer.
extern ACE_Export ACE_UINT16 crc_ccitt(const void *buf, size_t len,
ACE_UINT16 crc = 0);
/// Computes CRC-CCITT for the @ len iovec buffers.
extern ACE_Export ACE_UINT16 crc_ccitt(const iovec *iov, int len,
ACE_UINT16 crc = 0);
/// Computes the ISO 8802-3 standard 32 bits CRC for the string.
extern ACE_Export ACE_UINT32 crc32 (const char *str);
/// Computes the ISO 8802-3 standard 32 bits CRC for the buffer.
extern ACE_Export ACE_UINT32 crc32 (const void *buf, size_t len,
ACE_UINT32 crc = 0);
/// Computes the ISO 8802-3 standard 32 bits CRC for the
/// @ len iovec buffers.
extern ACE_Export ACE_UINT32 crc32 (const iovec *iov, int len,
ACE_UINT32 crc = 0);
/// Euclid's greatest common divisor algorithm.
extern ACE_Export u_long gcd (u_long x, u_long y);
/// Calculates the minimum enclosing frame size for the given values.
extern ACE_Export u_long minimum_frame_size (u_long period1, u_long period2);
/**
* Function that can burn up noticeable CPU time: brute-force
* determination of whether number @a n is prime. Returns 0 if
* it is prime, or the smallest factor if it is not prime.
* @a min_factor and @a max_factor can be used to partition the work
* among threads. For just one thread, typical values are 2 and
* n/2.
*/
extern ACE_Export u_long is_prime (const u_long n,
const u_long min_factor,
const u_long max_factor);
/// Map troublesome win32 errno values to values that standard C
/// strerr function understands. Thank you Microsoft.
extern ACE_Export int map_errno (int error);
/// Returns a string containing the error message corresponding to a
/// WinSock error. This works around an omission in the Win32 API.
/// @internal
extern ACE_Export const ACE_TCHAR * sock_error (int error);
/// Determins whether the given error code corresponds to to a
/// WinSock error. If so returns true, false otherwise.
/// @internal
extern ACE_Export bool is_sock_error (int error);
/**
* Checks if process with {pid} is still alive. Returns 1 if it is
* still alive, 0 if it isn't alive, and -1 if something weird
* happened.
*/
extern ACE_Export int process_active (pid_t pid);
/**
* Terminate the process abruptly with id @a pid. On Win32 platforms
* this uses {TerminateProcess} and on POSIX platforms is uses
* {kill} with the -9 (SIGKILL) signal, which cannot be caught or
* ignored. Note that this call is potentially dangerous to use
* since the process being terminated may not have a chance to
* cleanup before it shuts down.
*/
extern ACE_Export int terminate_process (pid_t pid);
/**
* This method uses process id and object pointer to come up with a
* machine wide unique name. The process ID will provide uniqueness
* between processes on the same machine. The "this" pointer of the
* {object} will provide uniqueness between other "live" objects in
* the same process. The uniqueness of this name is therefore only
* valid for the life of {object}.
*/
ACE_NAMESPACE_INLINE_FUNCTION void unique_name (const void *object,
ACE_TCHAR *name,
size_t length);
/// Computes the base 2 logarithm of {num}.
ACE_NAMESPACE_INLINE_FUNCTION u_long log2 (u_long num);
/// Helper to avoid comparing floating point values with ==
/// (uses < and > operators).
template <typename T>
bool is_equal (const T& a, const T& b)
{
return !((a < b) || (a > b));
}
/// Helper to avoid comparing floating point values with !=
/// (uses < and > operators).
template <typename T>
bool is_inequal (const T& a, const T& b)
{
return !is_equal (a, b);
}
/// Hex conversion utility.
extern ACE_Export ACE_TCHAR nibble2hex (u_int n);
/// Convert a hex character to its byte representation.
ACE_NAMESPACE_INLINE_FUNCTION u_char hex2byte (ACE_TCHAR c);
// = Set/get the debug level.
extern ACE_Export bool debug (void);
extern ACE_Export void debug (bool onoff);
/// Wrapper facade for @c select that uses @c ACE_Handle_Sets.
extern ACE_Export int select (int width,
ACE_Handle_Set *readfds,
ACE_Handle_Set *writefds = 0,
ACE_Handle_Set *exceptfds = 0,
const ACE_Time_Value *timeout = 0);
/// Wrapper facade for the most common use of @c select that uses
/// @c ACE_Handle_Sets.
extern ACE_Export int select (int width,
ACE_Handle_Set &readfds,
const ACE_Time_Value *timeout = 0);
/// Timed wait for handle to get read ready.
/// @retval -1 for error
/// @retval 0 for timeout
/// @retval 1 the handle is ready
ACE_NAMESPACE_INLINE_FUNCTION
int handle_read_ready (ACE_HANDLE handle,
const ACE_Time_Value *timeout);
/// Timed wait for handle to get write ready.
/// @retval -1 for error
/// @retval 0 for timeout
/// @retval 1 the handle is ready
ACE_NAMESPACE_INLINE_FUNCTION
int handle_write_ready (ACE_HANDLE handle,
const ACE_Time_Value *timeout);
/// Timed wait for handle to get exception ready.
/// @retval -1 for error
/// @retval 0 for timeout
/// @retval 1 the handle is ready
ACE_NAMESPACE_INLINE_FUNCTION
int handle_exception_ready (ACE_HANDLE handle,
const ACE_Time_Value *timeout);
/// Timed wait for handle to get read, write, or exception ready.
/// @retval -1 for error
/// @retval 0 for timeout
/// @retval 1 the handle is ready
extern ACE_Export int handle_ready (ACE_HANDLE handle,
const ACE_Time_Value *timeout,
int read_ready,
int write_ready,
int exception_ready);
/// Wait for @a timeout before proceeding to a @c recv operation.
/// @a val keeps track of whether we're in non-blocking mode or
/// not.
extern ACE_Export int enter_recv_timedwait (ACE_HANDLE handle,
const ACE_Time_Value *timeout,
int &val);
/// Wait for @a timeout before proceeding to a @c send operation.
/// @a val keeps track of whether we're in non-blocking mode or
/// not.
extern ACE_Export int enter_send_timedwait (ACE_HANDLE handle,
const ACE_Time_Value* timeout,
int &val);
/// This makes sure that @a handle is set into non-blocking mode.
/// @a val keeps track of whether were in non-blocking mode or not.
extern ACE_Export void record_and_set_non_blocking_mode (ACE_HANDLE handle,
int &val);
/// Cleanup after a timed operation, restore the appropriate
/// non-blocking status of @a handle.
extern ACE_Export void restore_non_blocking_mode (ACE_HANDLE handle,
int val);
// private:
// These functions aren't meant to be used internally, so they are
// not exported.
//
// = Recv_n helpers
//
ACE_NAMESPACE_INLINE_FUNCTION ssize_t recv_i (ACE_HANDLE handle,
void *buf,
size_t len);
extern ACE_Export ssize_t recv_n_i (ACE_HANDLE handle,
void *buf,
size_t len,
int flags,
size_t *bytes_transferred);
extern ACE_Export ssize_t recv_n_i (ACE_HANDLE handle,
void *buf,
size_t len,
int flags,
const ACE_Time_Value *timeout,
size_t *bytes_transferred);
#if defined (ACE_HAS_TLI)
extern ACE_Export ssize_t t_rcv_n_i (ACE_HANDLE handle,
void *buf,
size_t len,
int *flags,
size_t *bytes_transferred);
extern ACE_Export ssize_t t_rcv_n_i (ACE_HANDLE handle,
void *buf,
size_t len,
int *flags,
const ACE_Time_Value *timeout,
size_t *bytes_transferred);
#endif /* ACE_HAS_TLI */
extern ACE_Export ssize_t recv_n_i (ACE_HANDLE handle,
void *buf,
size_t len,
size_t *bytes_transferred);
extern ACE_Export ssize_t recv_n_i (ACE_HANDLE handle,
void *buf,
size_t len,
const ACE_Time_Value *timeout,
size_t *bytes_transferred);
extern ACE_Export ssize_t recvv_n_i (ACE_HANDLE handle,
iovec *iov,
int iovcnt,
size_t *bytes_transferred);
extern ACE_Export ssize_t recvv_n_i (ACE_HANDLE handle,
iovec *iov,
int iovcnt,
const ACE_Time_Value *timeout,
size_t *bytes_transferred);
//
// = Send_n helpers
//
ACE_NAMESPACE_INLINE_FUNCTION ssize_t send_i (ACE_HANDLE handle,
const void *buf,
size_t len);
extern ACE_Export ssize_t send_n_i (ACE_HANDLE handle,
const void *buf,
size_t len,
int flags,
size_t *bytes_transferred);
extern ACE_Export ssize_t send_n_i (ACE_HANDLE handle,
const void *buf,
size_t len,
int flags,
const ACE_Time_Value *timeout,
size_t *bytes_transferred);
#if defined (ACE_HAS_TLI)
extern ACE_Export ssize_t t_snd_n_i (ACE_HANDLE handle,
const void *buf,
size_t len,
int flags,
size_t *bytes_transferred);
extern ACE_Export ssize_t t_snd_n_i (ACE_HANDLE handle,
const void *buf,
size_t len,
int flags,
const ACE_Time_Value *timeout,
size_t *bytes_transferred);
#endif /* ACE_HAS_TLI */
extern ACE_Export ssize_t send_n_i (ACE_HANDLE handle,
const void *buf,
size_t len,
size_t *bytes_transferred);
extern ACE_Export ssize_t send_n_i (ACE_HANDLE handle,
const void *buf,
size_t len,
const ACE_Time_Value *timeout,
size_t *bytes_transferred);
extern ACE_Export ssize_t sendv_n_i (ACE_HANDLE handle,
const iovec *iov,
int iovcnt,
size_t *bytes_transferred);
extern ACE_Export ssize_t sendv_n_i (ACE_HANDLE handle,
const iovec *iov,
int iovcnt,
const ACE_Time_Value *timeout,
size_t *bytes_transferred);
}
// Close versioned namespace, if enabled by the user.
ACE_END_VERSIONED_NAMESPACE_DECL
#if defined (__ACE_INLINE__)
#include "ace/ACE.inl"
#endif /* __ACE_INLINE__ */
#include /**/ "ace/post.h"
#endif /* ACE_ACE_H */

View File

@@ -0,0 +1,333 @@
// -*- C++ -*-
//
// $Id: ACE.inl 95761 2012-05-15 18:23:04Z johnnyw $
#include "ace/OS_NS_unistd.h"
#include "ace/OS_NS_Thread.h"
#include "ace/OS_NS_ctype.h"
#include "ace/OS_NS_sys_socket.h"
// Open versioned namespace, if enabled by the user.
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
// Wrappers for methods that have been moved to ACE_OS.
ACE_INLINE ssize_t
ACE::read_n (ACE_HANDLE handle,
void *buf,
size_t len,
size_t *bytes_transferred)
{
return ACE_OS::read_n (handle,
buf,
len,
bytes_transferred);
}
ACE_INLINE ssize_t
ACE::write_n (ACE_HANDLE handle,
const void *buf,
size_t len,
size_t *bytes_transferred)
{
return ACE_OS::write_n (handle,
buf,
len,
bytes_transferred);
}
ACE_INLINE ssize_t
ACE::recv_n (ACE_HANDLE handle,
void *buf,
size_t len,
int flags,
const ACE_Time_Value *timeout,
size_t *bytes_transferred)
{
if (timeout == 0)
return ACE::recv_n_i (handle,
buf,
len,
flags,
bytes_transferred);
else
return ACE::recv_n_i (handle,
buf,
len,
flags,
timeout,
bytes_transferred);
}
#if defined (ACE_HAS_TLI)
ACE_INLINE ssize_t
ACE::t_rcv_n (ACE_HANDLE handle,
void *buf,
size_t len,
int *flags,
const ACE_Time_Value *timeout,
size_t *bytes_transferred)
{
if (timeout == 0)
return ACE::t_rcv_n_i (handle,
buf,
len,
flags,
bytes_transferred);
else
return ACE::t_rcv_n_i (handle,
buf,
len,
flags,
timeout,
bytes_transferred);
}
#endif /* ACE_HAS_TLI */
ACE_INLINE ssize_t
ACE::recv_n (ACE_HANDLE handle,
void *buf,
size_t len,
const ACE_Time_Value *timeout,
size_t *bytes_transferred)
{
if (timeout == 0)
return ACE::recv_n_i (handle,
buf,
len,
bytes_transferred);
else
return ACE::recv_n_i (handle,
buf,
len,
timeout,
bytes_transferred);
}
ACE_INLINE ssize_t
ACE::recvv_n (ACE_HANDLE handle,
iovec *iov,
int iovcnt,
const ACE_Time_Value *timeout,
size_t *bytes_transferred)
{
if (timeout == 0)
return ACE::recvv_n_i (handle,
iov,
iovcnt,
bytes_transferred);
else
return ACE::recvv_n_i (handle,
iov,
iovcnt,
timeout,
bytes_transferred);
}
ACE_INLINE ssize_t
ACE::send_n (ACE_HANDLE handle,
const void *buf,
size_t len,
int flags,
const ACE_Time_Value *timeout,
size_t *bytes_transferred)
{
if (timeout == 0)
return ACE::send_n_i (handle,
buf,
len,
flags,
bytes_transferred);
else
return ACE::send_n_i (handle,
buf,
len,
flags,
timeout,
bytes_transferred);
}
#if defined (ACE_HAS_TLI)
ACE_INLINE ssize_t
ACE::t_snd_n (ACE_HANDLE handle,
const void *buf,
size_t len,
int flags,
const ACE_Time_Value *timeout,
size_t *bytes_transferred)
{
if (timeout == 0)
return ACE::t_snd_n_i (handle,
buf,
len,
flags,
bytes_transferred);
else
return ACE::t_snd_n_i (handle,
buf,
len,
flags,
timeout,
bytes_transferred);
}
#endif /* ACE_HAS_TLI */
ACE_INLINE ssize_t
ACE::send_n (ACE_HANDLE handle,
const void *buf,
size_t len,
const ACE_Time_Value *timeout,
size_t *bytes_transferred)
{
if (timeout == 0)
return ACE::send_n_i (handle,
buf,
len,
bytes_transferred);
else
return ACE::send_n_i (handle,
buf,
len,
timeout,
bytes_transferred);
}
ACE_INLINE ssize_t
ACE::sendv_n (ACE_HANDLE handle,
const iovec *iov,
int iovcnt,
const ACE_Time_Value *timeout,
size_t *bytes_transferred)
{
if (timeout == 0)
return ACE::sendv_n_i (handle,
iov,
iovcnt,
bytes_transferred);
else
return ACE::sendv_n_i (handle,
iov,
iovcnt,
timeout,
bytes_transferred);
}
ACE_INLINE ssize_t
ACE::send_i (ACE_HANDLE handle, const void *buf, size_t len)
{
#if defined (ACE_WIN32) || defined (HPUX)
return ACE_OS::send (handle, (const char *) buf, len);
#else
return ACE_OS::write (handle, (const char *) buf, len);
#endif /* ACE_WIN32 */
}
ACE_INLINE ssize_t
ACE::recv_i (ACE_HANDLE handle, void *buf, size_t len)
{
#if defined (ACE_WIN32) || defined (ACE_OPENVMS)
return ACE_OS::recv (handle, (char *) buf, len);
#else
return ACE_OS::read (handle, (char *) buf, len);
#endif /* ACE_WIN32 */
}
ACE_INLINE int
ACE::handle_read_ready (ACE_HANDLE handle, const ACE_Time_Value *timeout)
{
return ACE::handle_ready (handle, timeout, 1, 0, 0);
}
ACE_INLINE int
ACE::handle_write_ready (ACE_HANDLE handle, const ACE_Time_Value *timeout)
{
return ACE::handle_ready (handle, timeout, 0, 1, 0);
}
ACE_INLINE int
ACE::handle_exception_ready (ACE_HANDLE handle, const ACE_Time_Value *timeout)
{
return ACE::handle_ready (handle, timeout, 0, 0, 1);
}
ACE_INLINE void
ACE::strdelete (char *s)
{
delete [] s;
}
#if defined (ACE_HAS_WCHAR)
ACE_INLINE void
ACE::strdelete (wchar_t *s)
{
delete [] s;
}
#endif /* ACE_HAS_WCHAR */
ACE_INLINE bool
ACE::isdotdir (const char *s)
{
return (s[0] == '.' &&
((s[1] == 0) || (s[1] == '.' && s[2] == 0)));
}
#if defined (ACE_HAS_WCHAR)
ACE_INLINE bool
ACE::isdotdir (const wchar_t *s)
{
return (s[0] == ACE_TEXT ('.') &&
((s[1] == 0) || (s[1] == ACE_TEXT ('.') && s[2] == 0)));
}
#endif /* ACE_HAS_WCHAR */
ACE_INLINE void
ACE::unique_name (const void *object,
ACE_TCHAR *name,
size_t length)
{
ACE_OS::unique_name (object, name, length);
}
ACE_INLINE u_long
ACE::log2 (u_long num)
{
u_long log = 0;
for (; num > 1; ++log)
num >>= 1;
return log;
}
ACE_INLINE int
ACE::map_errno (int error)
{
#if defined (ACE_WIN32)
switch (error)
{
case WSAEWOULDBLOCK:
return EAGAIN; // Same as UNIX errno EWOULDBLOCK.
}
#endif /* ACE_WIN32 */
return error;
}
ACE_INLINE u_char
ACE::hex2byte (ACE_TCHAR c)
{
if (ACE_OS::ace_isdigit (c))
return (u_char) (c - ACE_TEXT ('0'));
else if (ACE_OS::ace_islower (c))
return (u_char) (10 + c - ACE_TEXT ('a'));
else
return (u_char) (10 + c - ACE_TEXT ('A'));
}
// Close versioned namespace, if enabled by the user.
ACE_END_VERSIONED_NAMESPACE_DECL

View File

@@ -0,0 +1,10 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: ACE
Description: ADAPTIVE Communication Environment
Version: @VERSION@
Libs: -L${libdir} -lACE @LIBS@
Cflags: -I${includedir}

View File

@@ -0,0 +1,156 @@
// $Id: ACE_crc32.cpp 91286 2010-08-05 09:04:31Z johnnyw $
#include "ace/ACE.h"
namespace
{
/*****************************************************************/
/* */
/* CRC LOOKUP TABLE */
/* ================ */
/* The following CRC lookup table was generated automagically */
/* by the Rocksoft^tm Model CRC Algorithm Table Generation */
/* Program V1.0 using the following model parameters: */
/* */
/* Width : 4 bytes. */
/* Poly : 0x04C11DB7L */
/* Reverse : TRUE. */
/* */
/* For more information on the Rocksoft^tm Model CRC Algorithm, */
/* see the document titled "A Painless Guide to CRC Error */
/* Detection Algorithms" by Ross Williams */
/* (ross@guest.adelaide.edu.au.). This document is likely to be */
/* in the FTP archive "ftp.adelaide.edu.au/pub/rocksoft". */
/* */
/*****************************************************************/
const ACE_UINT32 crc_table[] =
{
0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL,
0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L,
0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L,
0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L,
0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL,
0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L,
0x136C9856L, 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL,
0x14015C4FL, 0x63066CD9L, 0xFA0F3D63L, 0x8D080DF5L,
0x3B6E20C8L, 0x4C69105EL, 0xD56041E4L, 0xA2677172L,
0x3C03E4D1L, 0x4B04D447L, 0xD20D85FDL, 0xA50AB56BL,
0x35B5A8FAL, 0x42B2986CL, 0xDBBBC9D6L, 0xACBCF940L,
0x32D86CE3L, 0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L,
0x26D930ACL, 0x51DE003AL, 0xC8D75180L, 0xBFD06116L,
0x21B4F4B5L, 0x56B3C423L, 0xCFBA9599L, 0xB8BDA50FL,
0x2802B89EL, 0x5F058808L, 0xC60CD9B2L, 0xB10BE924L,
0x2F6F7C87L, 0x58684C11L, 0xC1611DABL, 0xB6662D3DL,
0x76DC4190L, 0x01DB7106L, 0x98D220BCL, 0xEFD5102AL,
0x71B18589L, 0x06B6B51FL, 0x9FBFE4A5L, 0xE8B8D433L,
0x7807C9A2L, 0x0F00F934L, 0x9609A88EL, 0xE10E9818L,
0x7F6A0DBBL, 0x086D3D2DL, 0x91646C97L, 0xE6635C01L,
0x6B6B51F4L, 0x1C6C6162L, 0x856530D8L, 0xF262004EL,
0x6C0695EDL, 0x1B01A57BL, 0x8208F4C1L, 0xF50FC457L,
0x65B0D9C6L, 0x12B7E950L, 0x8BBEB8EAL, 0xFCB9887CL,
0x62DD1DDFL, 0x15DA2D49L, 0x8CD37CF3L, 0xFBD44C65L,
0x4DB26158L, 0x3AB551CEL, 0xA3BC0074L, 0xD4BB30E2L,
0x4ADFA541L, 0x3DD895D7L, 0xA4D1C46DL, 0xD3D6F4FBL,
0x4369E96AL, 0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L,
0x44042D73L, 0x33031DE5L, 0xAA0A4C5FL, 0xDD0D7CC9L,
0x5005713CL, 0x270241AAL, 0xBE0B1010L, 0xC90C2086L,
0x5768B525L, 0x206F85B3L, 0xB966D409L, 0xCE61E49FL,
0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L, 0xC7D7A8B4L,
0x59B33D17L, 0x2EB40D81L, 0xB7BD5C3BL, 0xC0BA6CADL,
0xEDB88320L, 0x9ABFB3B6L, 0x03B6E20CL, 0x74B1D29AL,
0xEAD54739L, 0x9DD277AFL, 0x04DB2615L, 0x73DC1683L,
0xE3630B12L, 0x94643B84L, 0x0D6D6A3EL, 0x7A6A5AA8L,
0xE40ECF0BL, 0x9309FF9DL, 0x0A00AE27L, 0x7D079EB1L,
0xF00F9344L, 0x8708A3D2L, 0x1E01F268L, 0x6906C2FEL,
0xF762575DL, 0x806567CBL, 0x196C3671L, 0x6E6B06E7L,
0xFED41B76L, 0x89D32BE0L, 0x10DA7A5AL, 0x67DD4ACCL,
0xF9B9DF6FL, 0x8EBEEFF9L, 0x17B7BE43L, 0x60B08ED5L,
0xD6D6A3E8L, 0xA1D1937EL, 0x38D8C2C4L, 0x4FDFF252L,
0xD1BB67F1L, 0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL,
0xD80D2BDAL, 0xAF0A1B4CL, 0x36034AF6L, 0x41047A60L,
0xDF60EFC3L, 0xA867DF55L, 0x316E8EEFL, 0x4669BE79L,
0xCB61B38CL, 0xBC66831AL, 0x256FD2A0L, 0x5268E236L,
0xCC0C7795L, 0xBB0B4703L, 0x220216B9L, 0x5505262FL,
0xC5BA3BBEL, 0xB2BD0B28L, 0x2BB45A92L, 0x5CB36A04L,
0xC2D7FFA7L, 0xB5D0CF31L, 0x2CD99E8BL, 0x5BDEAE1DL,
0x9B64C2B0L, 0xEC63F226L, 0x756AA39CL, 0x026D930AL,
0x9C0906A9L, 0xEB0E363FL, 0x72076785L, 0x05005713L,
0x95BF4A82L, 0xE2B87A14L, 0x7BB12BAEL, 0x0CB61B38L,
0x92D28E9BL, 0xE5D5BE0DL, 0x7CDCEFB7L, 0x0BDBDF21L,
0x86D3D2D4L, 0xF1D4E242L, 0x68DDB3F8L, 0x1FDA836EL,
0x81BE16CDL, 0xF6B9265BL, 0x6FB077E1L, 0x18B74777L,
0x88085AE6L, 0xFF0F6A70L, 0x66063BCAL, 0x11010B5CL,
0x8F659EFFL, 0xF862AE69L, 0x616BFFD3L, 0x166CCF45L,
0xA00AE278L, 0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L,
0xA7672661L, 0xD06016F7L, 0x4969474DL, 0x3E6E77DBL,
0xAED16A4AL, 0xD9D65ADCL, 0x40DF0B66L, 0x37D83BF0L,
0xA9BCAE53L, 0xDEBB9EC5L, 0x47B2CF7FL, 0x30B5FFE9L,
0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, 0x24B4A3A6L,
0xBAD03605L, 0xCDD70693L, 0x54DE5729L, 0x23D967BFL,
0xB3667A2EL, 0xC4614AB8L, 0x5D681B02L, 0x2A6F2B94L,
0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL, 0x2D02EF8DL
};
/*****************************************************************/
/* End of CRC Lookup Table */
/*****************************************************************/
}
#define COMPUTE(var, ch) (var) = (crc_table[(var ^ ch) & 0xFF] ^ (var >> 8))
// Open versioned namespace, if enabled by the user.
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
ACE_UINT32
ACE::crc32 (const char *string)
{
ACE_UINT32 crc = 0xFFFFFFFF;
for (const char *p = string;
*p != 0;
++p)
{
COMPUTE (crc, *p);
}
return ~crc;
}
ACE_UINT32
ACE::crc32 (const void *buffer, size_t len, ACE_UINT32 crc)
{
crc = ~crc;
for (const char *p = (const char *) buffer,
*e = (const char *) buffer + len;
p != e;
++p)
{
COMPUTE (crc, *p);
}
return ~crc;
}
ACE_UINT32
ACE::crc32 (const iovec *iov, int len, ACE_UINT32 crc)
{
crc = ~crc;
for (int i = 0; i < len; ++i)
{
for (const char *p = (const char *) iov[i].iov_base,
*e = (const char *) iov[i].iov_base + iov[i].iov_len;
p != e;
++p)
COMPUTE (crc, *p);
}
return ~crc;
}
// Close versioned namespace, if enabled by the user.
ACE_END_VERSIONED_NAMESPACE_DECL
#undef COMPUTE

View File

@@ -0,0 +1,124 @@
// $Id: ACE_crc_ccitt.cpp 96017 2012-08-08 22:18:09Z mitza $
#include "ace/ACE.h"
namespace
{
/*****************************************************************/
/* */
/* CRC LOOKUP TABLE */
/* ================ */
/* The following CRC lookup table was generated automagically */
/* by the Rocksoft^tm Model CRC Algorithm Table Generation */
/* Program V1.0 using the following model parameters: */
/* */
/* Width : 2 bytes. */
/* Poly : 0x1021 */
/* Reverse : TRUE. */
/* */
/* For more information on the Rocksoft^tm Model CRC Algorithm, */
/* see the document titled "A Painless Guide to CRC Error */
/* Detection Algorithms" by Ross Williams */
/* (ross@guest.adelaide.edu.au.). This document is likely to be */
/* in the FTP archive "ftp.adelaide.edu.au/pub/rocksoft". */
/* */
/*****************************************************************/
const ACE_UINT16 crc_table[] =
{
0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF,
0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7,
0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E,
0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876,
0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD,
0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5,
0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C,
0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974,
0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB,
0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3,
0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A,
0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72,
0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9,
0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1,
0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738,
0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70,
0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7,
0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF,
0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036,
0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E,
0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5,
0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD,
0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134,
0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C,
0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3,
0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB,
0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232,
0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A,
0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1,
0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9,
0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330,
0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78
};
/*****************************************************************/
/* End of CRC Lookup Table */
/*****************************************************************/
}
#define COMPUTE(var, ch) (var) = static_cast<ACE_UINT16> (crc_table[(var ^ ch) & 0xFF] ^ (var >> 8))
// Open versioned namespace, if enabled by the user.
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
ACE_UINT16
ACE::crc_ccitt (const char *string)
{
ACE_UINT16 crc = 0xFFFF;
for (const char *p = string;
*p != 0;
++p)
{
COMPUTE (crc, *p);
}
return static_cast<ACE_UINT16> (~crc);
}
ACE_UINT16
ACE::crc_ccitt (const void *buffer, size_t len, ACE_UINT16 crc)
{
crc = static_cast<ACE_UINT16> (~crc);
for (const char *p = (const char *) buffer,
*e = (const char *) buffer + len;
p != e;
++p)
{
COMPUTE (crc, *p);
}
return static_cast<ACE_UINT16> (~crc);
}
ACE_UINT16
ACE::crc_ccitt (const iovec *iov, int len, ACE_UINT16 crc)
{
crc = static_cast<ACE_UINT16> (~crc);
for (int i = 0; i < len; ++i)
{
for (const char *p = (const char *) iov[i].iov_base,
*e = (const char *) iov[i].iov_base + iov[i].iov_len;
p != e;
++p)
COMPUTE (crc, *p);
}
return static_cast<ACE_UINT16> (~crc);
}
// Close versioned namespace, if enabled by the user.
ACE_END_VERSIONED_NAMESPACE_DECL
#undef COMPUTE

View File

@@ -0,0 +1,74 @@
// -*- C++ -*-
// $Id: ACE_export.h 91683 2010-09-09 09:07:49Z johnnyw $
// Definition for Win32 Export directives.
// This file is generated automatically by
// generate_export_file.pl
// ------------------------------
#ifndef ACE_EXPORT_H
#define ACE_EXPORT_H
#include "ace/config-lite.h"
#if defined (ACE_AS_STATIC_LIBS)
# if !defined (ACE_HAS_DLL)
# define ACE_HAS_DLL 0
# endif /* ! ACE_HAS_DLL */
#else
# if !defined (ACE_HAS_DLL)
# define ACE_HAS_DLL 1
# endif /* ! ACE_HAS_DLL */
#endif /* ACE_AS_STATIC_LIB */
#if defined (ACE_HAS_DLL)
# if (ACE_HAS_DLL == 1)
# if defined (ACE_BUILD_DLL)
# define ACE_Export ACE_Proper_Export_Flag
# define ACE_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T)
# define ACE_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
# else
# define ACE_Export ACE_Proper_Import_Flag
# define ACE_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T)
# define ACE_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
# endif /* ACE_BUILD_DLL */
# else
# define ACE_Export
# define ACE_SINGLETON_DECLARATION(T)
# define ACE_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
# endif /* ! ACE_HAS_DLL == 1 */
#else
# define ACE_Export
# define ACE_SINGLETON_DECLARATION(T)
# define ACE_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
#endif /* ACE_HAS_DLL */
// Added by hand to help with ACE_OS namespace
#if defined (__TANDEM) && defined (USE_EXPLICIT_EXPORT)
#define ACE_NAMESPACE_STORAGE_CLASS ACE_EXPORT_MACRO extern
#else
#define ACE_NAMESPACE_STORAGE_CLASS extern ACE_EXPORT_MACRO
#endif
#if defined (__ACE_INLINE__)
# if defined (_MSC_VER) || defined (__MINGW32__) || defined (CYGWIN32) || \
(defined (__SUNPRO_CC) && __SUNPRO_CC >= 0x560) || \
(defined (__HP_aCC) && (__HP_aCC >= 60500))
# define ACE_NAMESPACE_INLINE_FUNCTION inline
# else
# define ACE_NAMESPACE_INLINE_FUNCTION ACE_NAMESPACE_STORAGE_CLASS inline
# endif
# define ACE_INLINE_TEMPLATE_FUNCTION inline
#else
# define ACE_NAMESPACE_INLINE_FUNCTION ACE_NAMESPACE_STORAGE_CLASS
// Microsoft Visual C++ will accept 'extern'; others refuse.
# if defined (_MSC_VER) || defined (__BORLANDC__)
# define ACE_INLINE_TEMPLATE_FUNCTION ACE_Export
# else
# define ACE_INLINE_TEMPLATE_FUNCTION
# endif
#endif
#endif /* ACE_EXPORT_H */
// End of auto generated file.

View File

@@ -0,0 +1,379 @@
#ifndef ACE_ARGV_CPP
#define ACE_ARGV_CPP
#include "ace/Log_Category.h"
#include "ace/OS_NS_unistd.h"
#include "ace/OS_NS_string.h"
#include "ace/OS_Memory.h"
#if !defined (__ACE_INLINE__)
#include "ace/ARGV.inl"
#endif /* __ACE_INLINE__ */
// Open versioned namespace, if enabled by the user.
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
ACE_ALLOC_HOOK_DEFINE (ACE_ARGV_Queue_Entry)
ACE_ALLOC_HOOK_DEFINE (ACE_ARGV)
template <typename CHAR_TYPE>
void
ACE_ARGV_Queue_Entry_T<CHAR_TYPE>::dump (void) const
{
#if defined (ACE_HAS_DUMP)
ACE_TRACE ("ACE_ARGV_Queue_Entry_T::dump");
ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("arg_ = %s"), this->arg_));
ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("quote_arg_ = %d"), (int)this->quote_arg_));
ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
#endif /* ACE_HAS_DUMP */
}
template <typename CHAR_TYPE>
void
ACE_ARGV_T<CHAR_TYPE>::dump (void) const
{
#if defined (ACE_HAS_DUMP)
ACE_TRACE ("ACE_ARGV_T::dump");
ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("argc_ = %d"), this->argc_));
ACE_ARGV *this_obj = const_cast<ACE_ARGV *> (this);
for (int i = 0; i < this->argc_; i++)
ACELIB_DEBUG ((LM_DEBUG,
ACE_TEXT ("\nargv_[%i] = %s"),
i,
this_obj->argv ()[i]));
ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("\nbuf = %s\n"), this->buf_));
ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("\n")));
ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
#endif /* ACE_HAS_DUMP */
}
// Creates this->argv_ out of this->buf_. New memory is allocated for
// each element of the array. This is used by the array-to-string
// style constructor and for creating this->argv_ when in iterative
// mode.
template <typename CHAR_TYPE>
int
ACE_ARGV_T<CHAR_TYPE>::string_to_argv (void)
{
ACE_TRACE ("ACE_ARGV_T::string_to_argv");
return ACE_OS::string_to_argv (this->buf_,
this->argc_,
this->argv_,
this->substitute_env_args_);
}
template <typename CHAR_TYPE>
ACE_ARGV_T<CHAR_TYPE>::ACE_ARGV_T (const CHAR_TYPE buf[],
bool substitute_env_args)
: substitute_env_args_ (substitute_env_args),
iterative_ (false),
argc_ (0),
argv_ (0),
buf_ (0),
length_ (0),
queue_ ()
{
ACE_TRACE ("ACE_ARGV_T::ACE_ARGV_T CHAR_TYPE[] to CHAR_TYPE *[]");
if (buf == 0 || buf[0] == 0)
return;
// Make an internal copy of the string.
ACE_NEW (this->buf_,
CHAR_TYPE[ACE_OS::strlen (buf) + 1]);
ACE_OS::strcpy (this->buf_, buf);
// Create this->argv_.
if (this->string_to_argv () == -1)
ACELIB_ERROR ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("string_to_argv")));
}
template <typename CHAR_TYPE>
ACE_ARGV_T<CHAR_TYPE>::ACE_ARGV_T (CHAR_TYPE *argv[],
bool substitute_env_args,
bool quote_arg)
: substitute_env_args_ (substitute_env_args),
iterative_ (false),
argc_ (0),
argv_ (0),
buf_ (0),
length_ (0),
queue_ ()
{
ACE_TRACE ("ACE_ARGV_T::ACE_ARGV_T CHAR_TYPE*[] to CHAR_TYPE[]");
if (argv == 0 || argv[0] == 0)
return;
this->argc_ = ACE_OS::argv_to_string (argv,
this->buf_,
substitute_env_args,
quote_arg);
}
template <typename CHAR_TYPE>
ACE_ARGV_T<CHAR_TYPE>::ACE_ARGV_T (int argc,
CHAR_TYPE *argv[],
bool substitute_env_args,
bool quote_arg)
: substitute_env_args_ (substitute_env_args),
iterative_ (false),
argc_ (0),
argv_ (0),
buf_ (0),
length_ (0),
queue_ ()
{
ACE_TRACE ("ACE_ARGV_T::ACE_ARGV_T int,CHAR_TYPE*[] to CHAR_TYPE[]");
this->argc_ = ACE_OS::argv_to_string (argc,
argv,
this->buf_,
substitute_env_args,
quote_arg);
}
template <typename CHAR_TYPE>
ACE_ARGV_T<CHAR_TYPE>::ACE_ARGV_T (CHAR_TYPE *first_argv[],
CHAR_TYPE *second_argv[],
bool substitute_env_args,
bool quote_args)
: substitute_env_args_ (substitute_env_args),
iterative_ (false),
argc_ (0),
argv_ (0),
buf_ (0),
length_ (0),
queue_ ()
{
ACE_TRACE ("ACE_ARGV_T::ACE_ARGV_T CHAR_TYPE*[] + CHAR_TYPE *[] to CHAR_TYPE[]");
int first_argc = 0;
int second_argc = 0;
CHAR_TYPE *first_buf = 0;
CHAR_TYPE *second_buf = 0;
size_t buf_len = 1;
// convert the first argv to a string
if (first_argv != 0 && first_argv[0] != 0)
{
first_argc = ACE_OS::argv_to_string (first_argv,
first_buf,
substitute_env_args,
quote_args);
buf_len += ACE_OS::strlen (first_buf);
}
// convert the second argv to a string
if (second_argv != 0 && second_argv[0] != 0)
{
second_argc = ACE_OS::argv_to_string (second_argv,
second_buf,
substitute_env_args,
quote_args);
buf_len += ACE_OS::strlen (second_buf);
}
// Add the number of arguments in both the argvs.
this->argc_ = first_argc + second_argc;
// Allocate memory to the lenght of the combined argv string.
ACE_NEW (this->buf_,
CHAR_TYPE[buf_len + 1]);
// copy the first argv string to the buffer
ACE_OS::strcpy (this->buf_, first_buf);
// concatenate the second argv string to the buffer
ACE_OS::strcat (this->buf_, second_buf);
// Delete the first and second buffers
delete [] first_buf;
delete [] second_buf;
}
template <typename CHAR_TYPE>
ACE_ARGV_T<CHAR_TYPE>::ACE_ARGV_T (bool substitute_env_args)
: substitute_env_args_ (substitute_env_args),
iterative_ (true),
argc_ (0),
argv_ (0),
buf_ (0),
length_ (0),
queue_ ()
{
ACE_TRACE ("ACE_ARGV_T::ACE_ARGV_T Iterative");
// Nothing to do yet -- the user puts in arguments via add ()
}
template <typename CHAR_TYPE>
int
ACE_ARGV_T<CHAR_TYPE>::add (const CHAR_TYPE *next_arg, bool quote_arg)
{
// Only allow this to work in the "iterative" verion -- the
// ACE_ARGVs created with the one argument constructor.
if (!this->iterative_)
{
errno = EINVAL;
return -1;
}
this->length_ += ACE_OS::strlen (next_arg);
if (quote_arg && ACE_OS::strchr (next_arg, ' ') != 0)
{
this->length_ += 2;
if (ACE_OS::strchr (next_arg, '"') != 0)
for (const CHAR_TYPE * p = next_arg; *p != '\0'; ++p)
if (*p == '"') ++this->length_;
}
else
{
quote_arg = false;
}
// Put the new argument at the end of the queue.
if (this->queue_.enqueue_tail (ACE_ARGV_Queue_Entry_T<CHAR_TYPE> (next_arg, quote_arg)) == -1)
ACELIB_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("Can't add more to ARGV queue")),
-1);
++this->argc_;
// Wipe argv_ and buf_ away so that they will be recreated if the
// user calls argv () or buf ().
if (this->argv_ != 0)
{
for (int i = 0; this->argv_[i] != 0; i++)
ACE_OS::free ((void *) this->argv_[i]);
delete [] this->argv_;
this->argv_ = 0;
}
delete [] this->buf_;
this->buf_ = 0;
return 0;
}
template <typename CHAR_TYPE>
int
ACE_ARGV_T<CHAR_TYPE>::add (CHAR_TYPE *argv[], bool quote_args)
{
for (int i = 0; argv[i] != 0; i++)
if (this->add (argv[i], quote_args) == -1)
return -1;
return 0;
}
// Free up argv_ and buf_
template <typename CHAR_TYPE>
ACE_ARGV_T<CHAR_TYPE>::~ACE_ARGV_T (void)
{
ACE_TRACE ("ACE_ARGV_T::~ACE_ARGV_T");
if (this->argv_ != 0)
for (int i = 0; this->argv_[i] != 0; i++)
ACE_OS::free ((void *) this->argv_[i]);
delete [] this->argv_;
delete [] this->buf_;
}
// Create buf_ out of the queue_. This is only used in the
// "iterative" mode.
template <typename CHAR_TYPE>
int
ACE_ARGV_T<CHAR_TYPE>::create_buf_from_queue (void)
{
ACE_TRACE ("ACE_ARGV_T::create_buf_from_queue");
// If the are no arguments, don't do anything
if (this->argc_ <= 0)
return -1;
delete [] this->buf_;
ACE_NEW_RETURN (this->buf_,
CHAR_TYPE[this->length_ + this->argc_],
-1);
// Get an iterator over the queue
ACE_Unbounded_Queue_Iterator<ACE_ARGV_Queue_Entry_T<CHAR_TYPE> > iter (this->queue_);
ACE_ARGV_Queue_Entry_T<CHAR_TYPE> *arg = 0;
CHAR_TYPE *ptr = this->buf_;
size_t len;
while (!iter.done ())
{
// Get next argument from the queue.
iter.next (arg);
iter.advance ();
if (arg->quote_arg_)
{
*ptr++ = '"';
if (ACE_OS::strchr (arg->arg_, '"') != 0)
{
CHAR_TYPE prev = 0;
for (const CHAR_TYPE * p = arg->arg_; *p != '\0'; ++p)
{
if (*p == '"' && prev != '\\') *ptr++ = '\\';
prev = *ptr++ = *p;
}
}
else
{
len = ACE_OS::strlen (arg->arg_);
// Copy the argument into buf_
ACE_OS::memcpy ((void *) ptr,
(const void *) (arg->arg_),
len * sizeof (CHAR_TYPE));
// Move the pointer down.
ptr += len;
}
*ptr++ = '"';
}
else
{
len = ACE_OS::strlen (arg->arg_);
// Copy the argument into buf_
ACE_OS::memcpy ((void *) ptr,
(const void *) (arg->arg_),
len * sizeof (CHAR_TYPE));
// Move the pointer down.
ptr += len;
}
// Put in an argument separating space.
*ptr++ = ' ';
}
// Put in the NUL terminator
ptr[-1] = '\0';
return 0;
}
// Close versioned namespace, if enabled by the user.
ACE_END_VERSIONED_NAMESPACE_DECL
#endif /* ACE_ARGV_CPP */

View File

@@ -0,0 +1,333 @@
// -*- C++ -*-
//==========================================================================
/**
* @file ARGV.h
*
* $Id: ARGV.h 95972 2012-07-26 10:20:42Z johnnyw $
*
* @author Doug Schmidt <schmidt@cs.wustl.edu>
* @author Everett Anderson <eea1@cs.wustl.edu>
*/
//==========================================================================
#ifndef ACE_ARGUMENT_VECTOR_H
#define ACE_ARGUMENT_VECTOR_H
#include /**/ "ace/pre.h"
#include /**/ "ace/ACE_export.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "ace/Global_Macros.h"
#include "ace/Unbounded_Queue.h"
// Open versioned namespace, if enabled by the user.
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
/**
* @class ACE_ARGV_Queue_Entry_T
*
* @brief An entry in the queue which keeps user supplied arguments.
*/
template <typename CHAR_TYPE>
class ACE_ARGV_Queue_Entry_T
{
public:
// = Initialization and termination.
/// Initialize a ACE_ARGV_Queue_Entry_T.
ACE_ARGV_Queue_Entry_T (void);
/**
* Initialize a ACE_ARGV_Queue_Entry_T.
*
* @param arg Pointer to an argument
*
* @param quote_arg The argument @a arg need to be quoted
* while adding to the vector.
*/
ACE_ARGV_Queue_Entry_T (const CHAR_TYPE *arg,
bool quote_arg);
/**
* Initialize a ACE_ARGV_Queue_Entry_T.
*
* @param entry Pointer to a queue entry
*/
ACE_ARGV_Queue_Entry_T (const ACE_ARGV_Queue_Entry_T<CHAR_TYPE> &entry);
/// We need this destructor to keep some compilers from complaining.
/// It's just a no-op, however.
~ACE_ARGV_Queue_Entry_T (void);
/// Dump the state of this object.
void dump (void) const;
// Declare the dynamic allocation hooks.
ACE_ALLOC_HOOK_DECLARE;
/// Pointer to the argument.
const CHAR_TYPE * arg_;
/// The argument need to be quoted while adding to the vector.
bool quote_arg_;
};
/**
* @class ACE_ARGV_T
*
* @brief Builds a counted argument vector (ala argc/argv) from either
* a string or a set of separate tokens. This class preserves whitespace
* within tokens only if the whitespace-containing token is enclosed in
* either single (') or double (") quotes. This is consistent with the
* expected behavior if an argument vector obtained using this class is
* passed to, for example, ACE_Get_Opt.
*
* This class can substitute environment variable values for tokens that
* are environment variable references (e.g., @c $VAR). This only works
* if the token is an environment variable reference and nothing else; it
* doesn't substitute environment variable references within a token.
* For example, @c $HOME/file will not substitute the value of the HOME
* environment variable.
*/
template <typename CHAR_TYPE>
class ACE_ARGV_T
{
public:
// = Initialization and termination.
/**
* Splits the specified string into an argument vector. Arguments in the
* string are delimited by whitespace. Whitespace-containing arguments
* must be enclosed in quotes, either single (') or double (").
*
* @param buf A nul-terminated CHAR_TYPE array to split into arguments
* for the vector.
*
* @param substitute_env_args If non-zero, any token that is an
* environment variable reference (e.g., @c $VAR) will have
* its environment variable value in the resultant vector
* in place of the environment variable name.
*/
explicit ACE_ARGV_T (const CHAR_TYPE buf[],
bool substitute_env_args = true);
/**
* Initializes the argument vector from a set of arguments. Any environment
* variable references are translated (if applicable) during execution of
* this method. In contrast with ACE_ARGV_T(CHAR_TYPE *[], bool, bool), this
* ctor does not require argv to be 0-terminated as the number of arguments
* is provided explicitely.
*
* @param argc The number of arguments in the argv array.
*
* @param argv An array of tokens to initialize the object with. All needed
* data is copied from @a argv during this call; the pointers
* in @a argv are not needed after this call, and the memory
* referred to by @a argv is not referenced by this object.
*
* @param substitute_env_args If non-zero, any element of @a argv that is
* an environment variable reference (e.g., @c $VAR) will have
* its environment variable value in the resultant vector
* in place of the environment variable name.
*
* @param quote_args If non-zero each argument @a argv[i] needs to
* be enclosed in double quotes ('"').
*/
explicit ACE_ARGV_T (int argc,
CHAR_TYPE *argv[],
bool substitute_env_args = true,
bool quote_args = false);
/**
* Initializes the argument vector from a set of arguments. Any environment
* variable references are translated (if applicable) during execution of
* this method.
*
* @param argv An array of tokens to initialize the object with. The
* array must be terminated with a 0 pointer. All needed
* data is copied from @a argv during this call; the pointers
* in @a argv are not needed after this call, and the memory
* referred to by @a argv is not referenced by this object.
*
* @param substitute_env_args If non-zero, any element of @a argv that is
* an environment variable reference (e.g., @c $VAR) will have
* its environment variable value in the resultant vector
* in place of the environment variable name.
*
* @param quote_args If non-zero each argument @a argv[i] needs to
* be enclosed in double quotes ('"').
*/
explicit ACE_ARGV_T (CHAR_TYPE *argv[],
bool substitute_env_args = true,
bool quote_args = false);
/**
* Initializes the argument vector from two combined argument vectors.
*
* @param first_argv An array of tokens to initialize the object with.
* The array must be terminated with a 0 pointer.
* @param second_argv An array of tokens that is concatenated with the
* the tokens in @a first_argv. The array must be
* terminated with a 0 pointer.
* @param substitute_env_args If non-zero, any element of @a first_argv
* or @a second_argv that is an environment variable
* reference (e.g., @c $VAR) will have its environment
* variable value in the resultant vector in place
* of the environment variable name.
*
* @param quote_args If non-zero each arguments @a first_argv[i] and
* @a second_argv[i] needs to be enclosed
* in double quotes ('"').
*/
ACE_ARGV_T (CHAR_TYPE *first_argv[],
CHAR_TYPE *second_argv[],
bool substitute_env_args = true,
bool quote_args = false);
/**
* Initialize this object so arguments can be added later using one
* of the add methods. This is referred to as the @i iterative method
* of adding arguments to this object.
*/
explicit ACE_ARGV_T (bool substitute_env_args = true);
/// Destructor.
~ACE_ARGV_T (void);
/** @name Accessor methods
*
* These methods access the argument vector contained in this object.
*/
//@{
/**
* Returns the specified element of the current argument vector.
*
* @param index Index to the desired element.
*
* @retval Pointer to the indexed string.
* @retval 0 if @a index is out of bounds.
*/
const CHAR_TYPE *operator[] (size_t index);
/**
* Returns the current argument vector. The returned pointers are to data
* maintained internally to this class. Do not change or delete either the
* pointers or the memory to which they refer.
*/
CHAR_TYPE **argv (void);
/// Returns the current number of arguments.
int argc (void) const;
/**
* Returns a single string form of the current arguments. The returned
* pointer refers to memory maintained internally to this class. Do not
* change or delete it.
*/
const CHAR_TYPE *buf (void);
//@}
/// Dump the state of this object.
void dump (void) const;
// Declare the dynamic allocation hooks.
ACE_ALLOC_HOOK_DECLARE;
/**
* Add another argument. This only works in the iterative mode.
*
* @note This method copies the specified pointer, but not the data
* contained in the referenced memory. Thus, if the content of
* the memory referred to by @a next_arg are changed after this
* method returns, the results are undefined.
*
* @param next_arg Pointer to the next argument to add to the vector.
*
* @param quote_arg The argument @a next_arg need to be quoted while
* adding to the vector.
*
* @retval 0 on success; -1 on failure. Most likely @c errno values are:
* - EINVAL: This object is not in iterative mode.
* - ENOMEM: Not enough memory available to save @a next_arg.
*/
int add (const CHAR_TYPE *next_arg, bool quote_arg = false);
/**
* Add an array of arguments. This only works in the iterative mode.
*
* @note This method copies the specified pointers, but not the data
* contained in the referenced memory. Thus, if the content of
* the memory referred to by any of the @a argv elements is
* changed after this method returns, the results are undefined.
*
* @param argv Pointers to the arguments to add to the vector.
* @a argv must be terminated by a 0 pointer.
*
* @param quote_args If non-zero each argument @a argv[i] needs to
* be enclosed in double quotes ('"').
*
* @retval 0 on success; -1 on failure. Most likely @c errno values are:
* - EINVAL: This object is not in iterative mode.
* - ENOMEM: Not enough memory available to save @a next_arg.
*/
int add (CHAR_TYPE *argv[], bool quote_args = false);
private:
/// Copy constructor not implemented.
ACE_UNIMPLEMENTED_FUNC (ACE_ARGV_T (const ACE_ARGV_T<CHAR_TYPE>&))
/// Assignment operator not implemented.
ACE_UNIMPLEMENTED_FUNC (ACE_ARGV_T operator= (const ACE_ARGV_T<CHAR_TYPE>&))
/// Creates buf_ from the queue of added args, deletes previous buf_.
int create_buf_from_queue (void);
/// Converts buf_ into the CHAR_TYPE *argv[] format.
int string_to_argv (void);
/// Replace args with environment variable values?
bool substitute_env_args_;
bool iterative_;
/// Number of arguments in the ARGV array.
int argc_;
/// The array of string arguments.
CHAR_TYPE **argv_;
/// Buffer containing the <argv> contents.
CHAR_TYPE *buf_;
/// Total length of the arguments in the queue, not counting
/// separating spaces
size_t length_;
/// Queue which keeps user supplied arguments. This is only
/// active in the "iterative" mode.
ACE_Unbounded_Queue<ACE_ARGV_Queue_Entry_T<CHAR_TYPE> > queue_;
};
typedef ACE_ARGV_Queue_Entry_T<ACE_TCHAR> ACE_ARGV_Queue_Entry;
typedef ACE_ARGV_T<ACE_TCHAR> ACE_ARGV;
// Close versioned namespace, if enabled by the user.
ACE_END_VERSIONED_NAMESPACE_DECL
#if defined (__ACE_INLINE__)
#include "ace/ARGV.inl"
#endif /* __ACE_INLINE__ */
#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
#include "ace/ARGV.cpp"
#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
#pragma implementation ("ARGV.cpp")
#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
#include /**/ "ace/post.h"
#endif /* ACE_ARGUMENT_VECTOR_H */

View File

@@ -0,0 +1,104 @@
/* -*- C++ -*- */
// $Id: ARGV.inl 80826 2008-03-04 14:51:23Z wotte $
#include "ace/Global_Macros.h"
// Open versioned namespace, if enabled by the user.
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
template <typename CHAR_TYPE> ACE_INLINE
ACE_ARGV_Queue_Entry_T<CHAR_TYPE>::ACE_ARGV_Queue_Entry_T (void)
: arg_(0),
quote_arg_(false)
{
// No-op
}
template <typename CHAR_TYPE> ACE_INLINE
ACE_ARGV_Queue_Entry_T<CHAR_TYPE>::ACE_ARGV_Queue_Entry_T (const CHAR_TYPE *arg,
bool quote_arg)
: arg_(arg),
quote_arg_(quote_arg)
{
// No-op
}
template <typename CHAR_TYPE> ACE_INLINE
ACE_ARGV_Queue_Entry_T<CHAR_TYPE>::ACE_ARGV_Queue_Entry_T (const ACE_ARGV_Queue_Entry_T<CHAR_TYPE> &entry)
: arg_(entry.arg_),
quote_arg_(entry.quote_arg_)
{
// No-op
}
template <typename CHAR_TYPE> ACE_INLINE
ACE_ARGV_Queue_Entry_T<CHAR_TYPE>::~ACE_ARGV_Queue_Entry_T (void)
{
// No-op just to keep some compilers happy...
}
// Return the number of args
template <typename CHAR_TYPE>
ACE_INLINE int
ACE_ARGV_T<CHAR_TYPE>::argc (void) const
{
ACE_TRACE ("ACE_ARGV_T::argc");
// Try to create the argv_ if it isn't there
ACE_ARGV_T<CHAR_TYPE> *nonconst_this =
const_cast <ACE_ARGV_T<CHAR_TYPE> *> (this);
(void) nonconst_this->argv ();
return this->argc_;
}
// Return the arguments in a space-separated string
template <typename CHAR_TYPE>
ACE_INLINE const CHAR_TYPE *
ACE_ARGV_T<CHAR_TYPE>::buf (void)
{
ACE_TRACE ("ACE_ARGV_T::buf");
if (this->buf_ == 0 && this->iterative_)
this->create_buf_from_queue ();
return (const CHAR_TYPE *) this->buf_;
}
// Return the arguments in an entry-per-argument array
template <typename CHAR_TYPE>
ACE_INLINE CHAR_TYPE **
ACE_ARGV_T<CHAR_TYPE>::argv (void)
{
ACE_TRACE ("ACE_ARGV_T::argv");
// Try to create the argv_ if it isn't there
if (this->argv_ == 0)
{
if (this->iterative_ && this->buf_ == 0)
this->create_buf_from_queue ();
// Convert buf_ to argv_
if (this->string_to_argv () == -1)
return (CHAR_TYPE **) 0;
}
return (CHAR_TYPE **) this->argv_;
}
// Subscript operator.
template <typename CHAR_TYPE>
ACE_INLINE const CHAR_TYPE *
ACE_ARGV_T<CHAR_TYPE>::operator[] (size_t i)
{
ACE_TRACE ("ACE_ARGV_T::operator[]");
// Don't go out of bounds.
if (i >= static_cast<size_t> (this->argc_))
return 0;
return (const CHAR_TYPE *) this->argv ()[i];
}
// Close versioned namespace, if enabled by the user.
ACE_END_VERSIONED_NAMESPACE_DECL

View File

@@ -0,0 +1,307 @@
#include "ace/ATM_Acceptor.h"
#if defined (ACE_HAS_ATM)
#if defined (ACE_HAS_LINUX_ATM)
#include /**/ "linux/atmdev.h"
#endif /* ACE_HAS_LINUX_ATM */
#if !defined (__ACE_INLINE__)
#include "ace/ATM_Acceptor.inl"
#endif /* __ACE_INLINE__ */
// Open versioned namespace, if enabled by the user.
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
// Put the actual definitions of the ACE_ATM_Request and
// ACE_ATM_Request_Queue classes here to hide them from clients...
ACE_ALLOC_HOOK_DEFINE(ACE_ATM_Acceptor)
ACE_ATM_Acceptor::ACE_ATM_Acceptor (void)
{
ACE_TRACE ("ACE_ATM_Acceptor::ACE_ATM_Acceptor");
}
ACE_ATM_Acceptor::~ACE_ATM_Acceptor (void)
{
ACE_TRACE ("ACE_ATM_Acceptor::~ACE_ATM_Acceptor");
}
int
ACE_ATM_Acceptor::get_local_addr (ACE_ATM_Addr &local_addr)
{
ACE_TRACE ("ACE_ATM_Acceptor::get_local_addr");
#if defined (ACE_HAS_FORE_ATM_WS2)
unsigned long ret = 0;
DWORD deviceID = 0;
ATM_ADDRESS addr;
struct sockaddr_atm *laddr;
if (::WSAIoctl ((int) ((ACE_SOCK_Acceptor *)this) -> get_handle (),
SIO_GET_ATM_ADDRESS,
(LPVOID) &deviceID,
sizeof (DWORD),
(LPVOID)&addr,
sizeof (ATM_ADDRESS),
&ret,
0,
0) == SOCKET_ERROR) {
ACE_OS::printf ("ATM_Acceptor (get_local_addr): WSIoctl: %d\n",
::WSAGetLastError ());
return -1;
}
laddr = (struct sockaddr_atm *)local_addr.get_addr ();
ACE_OS::memcpy ((void *)& (laddr -> satm_number),
(void *)&addr,
ATM_ADDR_SIZE - 1);
return 0;
#elif defined (ACE_HAS_FORE_ATM_XTI)
ACE_UNUSED_ARG (local_addr);
return 0;
#elif defined (ACE_HAS_LINUX_ATM)
ATM_Addr *myaddr = (ATM_Addr *)local_addr.get_addr ();
int addrlen = sizeof (myaddr->sockaddratmsvc);
if (ACE_OS::getsockname (acceptor_.get_handle (),
(struct sockaddr *) & (myaddr->sockaddratmsvc),
&addrlen) < 0) {
ACELIB_DEBUG ((LM_DEBUG,
ACE_TEXT ("ATM_Acceptor (get_local_addr): ioctl: %d\n"),
errno));
return -1;
}
return 0;
#else
ACE_UNUSED_ARG (local_addr);
return 0;
#endif /* ACE_HAS_FORE_ATM_WS2 && ACE_HAS_FORE_ATM_XTI */
}
ACE_HANDLE
ACE_ATM_Acceptor::open (const ACE_Addr &remote_sap,
int backlog,
ACE_ATM_Params params)
{
ACE_TRACE ("ACE_ATM_Acceptor::open");
#if defined (ACE_HAS_FORE_ATM_XTI)
ACE_HANDLE handle = acceptor_.open (remote_sap,
params.get_reuse_addr (),
params.get_oflag (),
params.get_info (),
backlog,
params.get_device ());
return (handle == ACE_INVALID_HANDLE ? -1 : 0);
#elif defined (ACE_HAS_FORE_ATM_WS2)
struct sockaddr_atm local_atm_addr;
ACE_HANDLE ret;
DWORD flags = 0;
/* Create a local endpoint of communication */
// Only leaves can listen.
flags = ACE_FLAG_MULTIPOINT_C_LEAF | ACE_FLAG_MULTIPOINT_D_LEAF;
if ((ret = ACE_OS::socket (AF_ATM,
SOCK_RAW,
ATMPROTO_AAL5,
0,
0,
flags))
== ACE_INVALID_HANDLE) {
ACE_OS::printf ("Acceptor (open): socket %d\n",
::WSAGetLastError ());
return (ret);
}
((ACE_SOCK_Acceptor *)this) -> set_handle (ret);
/* Set up the address information to become a server */
ACE_OS::memset ((void *) &local_atm_addr, 0, sizeof local_atm_addr);
local_atm_addr.satm_family = AF_ATM;
local_atm_addr.satm_number.AddressType = SAP_FIELD_ANY_AESA_REST;
local_atm_addr.satm_number.Addr[ ATM_ADDR_SIZE - 1 ]
= ((ACE_ATM_Addr *)&remote_sap) -> get_selector ();
local_atm_addr.satm_blli.Layer2Protocol = SAP_FIELD_ANY;
local_atm_addr.satm_blli.Layer3Protocol = SAP_FIELD_ABSENT;
local_atm_addr.satm_bhli.HighLayerInfoType = SAP_FIELD_ABSENT;
/* Associate address with endpoint */
if (ACE_OS::bind (((ACE_SOCK_Acceptor *)this) -> get_handle (),
reinterpret_cast<struct sockaddr *> (&local_atm_addr),
sizeof local_atm_addr) == -1) {
ACE_OS::printf ("Acceptor (open): bind %d\n", ::WSAGetLastError ());
return (ACE_INVALID_HANDLE);
}
/* Make endpoint listen for service requests */
if (ACE_OS::listen (( (ACE_SOCK_Acceptor *)this) -> get_handle (),
backlog)
== -1) {
ACE_OS::printf ("Acceptor (open): listen %d\n", ::WSAGetLastError ());
return (ACE_INVALID_HANDLE);
}
return 0;
#elif defined (ACE_HAS_LINUX_ATM)
//we need to set the qos before binding to the socket
//use remote_sap as local_sap
ACE_ATM_Addr local_sap;
ATM_Addr *local_sap_addr = (ATM_Addr*)local_sap.get_addr ();
ACE_ATM_QoS def_qos;
ATM_QoS qos = def_qos.get_qos ();
ACE_HANDLE handle;
if ((handle = ACE_OS::socket (params.get_protocol_family (),
params.get_type (),
params.get_protocol (),
params.get_protocol_info (),
params.get_sock_group (),
params.get_flags ()
))
== ACE_INVALID_HANDLE) {
ACELIB_DEBUG (LM_DEBUG,
ACE_TEXT ("Acceptor (socket): socket %d\n"),
errno);
return (ACE_INVALID_HANDLE);
}
((ACE_SOCK_Acceptor *)this) -> set_handle (handle);
if (ACE_OS::setsockopt (handle,
SOL_ATM,
SO_ATMQOS,
reinterpret_cast<char*> (&qos),
sizeof (qos)) < 0) {
ACE_OS::printf ("Acceptor (setsockopt): setsockopt:%d\n",
errno);
}
struct atmif_sioc req;
struct sockaddr_atmsvc aux_addr[1024];
req.number = 0;
req.arg = aux_addr;
req.length = sizeof (aux_addr);
if (ACE_OS::ioctl (handle,
ATM_GETADDR,
&req) < 0) {
ACE_OS::perror ("Acceptor (setsockopt): ioctl:");
}
else {
local_sap_addr->sockaddratmsvc = aux_addr[0];
}
local_sap.set_selector (( (ACE_ATM_Addr*)&remote_sap)->get_selector ());
if (ACE_OS::bind (handle,
reinterpret_cast<struct sockaddr *> (
&(local_sap_addr->sockaddratmsvc)),
sizeof (local_sap_addr->sockaddratmsvc)
) == -1) {
ACELIB_DEBUG (LM_DEBUG,
ACE_TEXT ("Acceptor (open): bind %d\n"),
errno);
return -1;
}
// Make endpoint listen for service requests
if (ACE_OS::listen (handle,
backlog)
== -1) {
ACELIB_DEBUG (LM_DEBUG,
ACE_TEXT ("Acceptor (listen): listen %d\n"),
errno);
return -1;
}
return 0;
#else
ACE_UNUSED_ARG (remote_sap);
ACE_UNUSED_ARG (backlog);
ACE_UNUSED_ARG (params);
#endif /* ACE_HAS_FORE_ATM_XTI/ACE_HAS_FORE_ATM_WS2/ACE_HAS_LINUX_ATM */
}
int
ACE_ATM_Acceptor::accept (ACE_ATM_Stream &new_sap,
ACE_Addr *remote_addr,
ACE_Time_Value *timeout,
bool restart,
bool reset_new_handle,
ACE_ATM_Params params,
ACE_ATM_QoS qos)
{
ACE_TRACE ("ACE_ATM_Acceptor::accept");
#if defined (ACE_HAS_FORE_ATM_XTI)
ATM_QoS optbuf = qos.get_qos ();
return (acceptor_.accept (new_sap.get_stream (),
remote_addr,
timeout,
restart,
reset_new_handle,
params.get_rw_flag (),
params.get_user_data (),
&optbuf));
#elif defined (ACE_HAS_FORE_ATM_WS2)
ACE_HANDLE n_handle;
ACE_HANDLE s_handle = ((ACE_SOCK_Acceptor *) this) -> get_handle ();
struct sockaddr_atm *cli_addr
= (struct sockaddr_atm *)remote_addr -> get_addr ();
int caddr_len = sizeof (struct sockaddr_atm);
do {
n_handle = ACE_OS::accept (s_handle,
reinterpret_cast<struct sockaddr *> (cli_addr),
&caddr_len);
} while (n_handle == ACE_INVALID_HANDLE && errno == EINTR);
((ACE_ATM_Addr *)remote_addr) -> set (cli_addr,
((ACE_ATM_Addr *)remote_addr) -> get_selector ());
((ACE_IPC_SAP *)&new_sap) -> set_handle (n_handle);
return 0;
#elif defined (ACE_HAS_LINUX_ATM)
ACE_UNUSED_ARG (params);
ACE_HANDLE s_handle = ((ACE_SOCK_Acceptor *) this) -> get_handle ();
struct atm_qos accept_qos = qos.get_qos ();
if (ACE_OS::setsockopt (s_handle,
SOL_ATM,
SO_ATMQOS,
reinterpret_cast<char*> (&accept_qos),
sizeof (accept_qos)) < 0) {
ACE_OS::printf ("Acceptor (accept): error setting Qos");
}
return (acceptor_.accept (new_sap.get_stream (),
remote_addr,
timeout,
restart,
reset_new_handle));
#else
ACE_UNUSED_ARG (new_sap);
ACE_UNUSED_ARG (remote_addr);
ACE_UNUSED_ARG (timeout);
ACE_UNUSED_ARG (restart);
ACE_UNUSED_ARG (reset_new_handle);
ACE_UNUSED_ARG (params);
ACE_UNUSED_ARG (qos);
return 0;
#endif /* ACE_HAS_FORE_ATM_XTI */
}
// Close versioned namespace, if enabled by the user.
ACE_END_VERSIONED_NAMESPACE_DECL
#endif /* ACE_HAS_ATM */

View File

@@ -0,0 +1,121 @@
// -*- C++ -*-
//=============================================================================
/**
* @file ATM_Acceptor.h
*
* @author Joe Hoffert
*/
//=============================================================================
#ifndef ACE_ATM_ACCEPTOR_H
#define ACE_ATM_ACCEPTOR_H
#include /**/ "ace/pre.h"
#include /**/ "ace/config-all.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#if defined (ACE_HAS_ATM)
#include "ace/ATM_Stream.h"
#include "ace/ATM_Params.h"
#include "ace/ATM_QoS.h"
#if defined (ACE_HAS_LINUX_ATM)
#include /**/ "atm.h"
#endif /* ACE_HAS_LINUX_ATM */
#if defined (ACE_HAS_FORE_ATM_WS2) || defined (ACE_HAS_LINUX_ATM)
#include "ace/SOCK_Acceptor.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
typedef ACE_SOCK_Acceptor ATM_Acceptor;
ACE_END_VERSIONED_NAMESPACE_DECL
#elif defined (ACE_HAS_FORE_ATM_XTI)
#include "ace/TLI_Acceptor.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
typedef ACE_TLI_Acceptor ATM_Acceptor;
ACE_END_VERSIONED_NAMESPACE_DECL
#endif // ACE_HAS_FORE_ATM_WS2 || ACE_HAS_LINUX_ATM
// Open versioned namespace, if enabled by the user.
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
// Forward declarations.
class ACE_Time_Value;
/**
* @class ACE_ATM_Acceptor
*
* @brief Defines the member functions for ACE_ATM_Acceptor abstraction.
*
* This class wraps up the ACE_SOCK_Acceptor and ACE_TLI_Acceptor
* to make the mechanism for the ATM protocol transparent.
*/
class ACE_Export ACE_ATM_Acceptor
{
public:
// = Initialization and termination methods.
/// Default constructor.
ACE_ATM_Acceptor (void);
~ACE_ATM_Acceptor ();
/// Initiate a passive mode connection.
ACE_ATM_Acceptor (const ACE_Addr &remote_sap,
int backlog = ACE_DEFAULT_BACKLOG,
ACE_ATM_Params params = ACE_ATM_Params());
/// Initiate a passive mode socket.
ACE_HANDLE open (const ACE_Addr &remote_sap,
int backlog = ACE_DEFAULT_BACKLOG,
ACE_ATM_Params params = ACE_ATM_Params());
/// Close down the acceptor and release resources.
int close (void);
// = Passive connection acceptance method.
/// Accept a new data transfer connection. A @a timeout of 0 means
/// block forever, a @a timeout of {0, 0} means poll. @a restart == 1
/// means "restart if interrupted."
int accept (ACE_ATM_Stream &new_sap,
ACE_Addr *remote_addr = 0,
ACE_Time_Value *timeout = 0,
bool restart = true,
bool reset_new_handle = false,
ACE_ATM_Params params = ACE_ATM_Params(),
ACE_ATM_QoS qos = ACE_ATM_QoS());
/// Get the local address currently listening on
int get_local_addr( ACE_ATM_Addr &local_addr );
// = Meta-type info
typedef ACE_ATM_Addr PEER_ADDR;
typedef ACE_ATM_Stream PEER_STREAM;
/// Dump the state of an object.
void dump (void) const;
/// Declare the dynamic allocation hooks.
ACE_ALLOC_HOOK_DECLARE;
private:
ATM_Acceptor acceptor_;
};
// Close versioned namespace, if enabled by the user.
ACE_END_VERSIONED_NAMESPACE_DECL
#if defined (__ACE_INLINE__)
#include "ace/ATM_Acceptor.inl"
#endif /* __ACE_INLINE__ */
#endif /* ACE_HAS_ATM */
#include /**/ "ace/post.h"
#endif /* ACE_ATM_ACCEPTOR_H */

View File

@@ -0,0 +1,40 @@
// -*- C++ -*-
// Open versioned namespace, if enabled by the user.
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
ACE_INLINE void
ACE_ATM_Acceptor::dump (void) const
{
#if defined (ACE_HAS_DUMP)
ACE_TRACE ("ACE_ATM_Acceptor::dump");
#endif /* ACE_HAS_DUMP */
}
ACE_INLINE
ACE_ATM_Acceptor::ACE_ATM_Acceptor (const ACE_Addr &remote_sap,
int backlog,
ACE_ATM_Params params)
{
ACE_TRACE ("ACE_ATM_Acceptor::ACE_ATM_Acceptor");
//FUZZ: disable check_for_lack_ACE_OS
if (open (remote_sap, backlog, params) < 0)
//FUZZ: enable check_for_lack_ACE_OS
ACELIB_ERROR ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("ACE_ATM_Acceptor::ACE_ATM_Acceptor")));
}
ACE_INLINE
int
ACE_ATM_Acceptor::close (void)
{
#if defined (ACE_HAS_FORE_ATM_XTI) || defined (ACE_HAS_FORE_ATM_WS2) || defined (ACE_HAS_LINUX_ATM)
return (acceptor_.close());
#else
return 0;
#endif // ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 || ACE_HAS_LINUX_ATM
}
// Close versioned namespace, if enabled by the user.
ACE_END_VERSIONED_NAMESPACE_DECL

View File

@@ -0,0 +1,519 @@
// Defines the Internet domain address family address format.
#include "ace/ATM_Addr.h"
#if defined (ACE_HAS_ATM)
#include "ace/Log_Category.h"
#if defined (ACE_HAS_FORE_ATM_WS2)
#include /**/ "forews2.h"
#endif /* ACE_HAS_FORE_ATM_WS2 */
#if !defined (__ACE_INLINE__)
#include "ace/ATM_Addr.inl"
#endif /* __ACE_INLINE__ */
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
ACE_ALLOC_HOOK_DEFINE(ACE_ATM_Addr)
#if defined (ACE_HAS_FORE_ATM_XTI) || defined (ACE_HAS_FORE_ATM_WS2)
#define BHLI_MAGIC "FORE_ATM"
// This is line rate in cells/s for an OC-3 MM interface.
const long ACE_ATM_Addr::LINE_RATE = 353207;
const int ACE_ATM_Addr::OPT_FLAGS_CPID = 0x1;
const int ACE_ATM_Addr::OPT_FLAGS_PMP = 0x2;
const int ACE_ATM_Addr::DEFAULT_SELECTOR = 0x99;
#elif defined (ACE_HAS_LINUX_ATM)
//pbrandao:for Linux:
//pbrandao:for now stick with current definitions
//pbrandao:see if later need to change
const long ACE_ATM_Addr::LINE_RATE = 353207;
const int ACE_ATM_Addr::OPT_FLAGS_CPID = 0;
const int ACE_ATM_Addr::OPT_FLAGS_PMP = 0;
const int ACE_ATM_Addr::DEFAULT_SELECTOR = 0x99;
#else
const long ACE_ATM_Addr::LINE_RATE = 0L;
const int ACE_ATM_Addr::OPT_FLAGS_CPID = 0;
const int ACE_ATM_Addr::OPT_FLAGS_PMP = 0;
const int ACE_ATM_Addr::DEFAULT_SELECTOR = 0x0;
#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 || ACE_HAS_LINUX_ATM */
// Default constructor
ACE_ATM_Addr::ACE_ATM_Addr (u_char selector)
#if defined (ACE_HAS_FORE_ATM_XTI) || defined (ACE_HAS_FORE_ATM_WS2)
: ACE_Addr (AF_ATM,
#elif defined (ACE_HAS_LINUX_ATM)
: ACE_Addr (PF_ATMSVC,
#else
: ACE_Addr (AF_UNSPEC,
#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 || ACE_HAS_LINUX_ATM */
sizeof this->atm_addr_)
{
// ACE_TRACE ("ACE_ATM_Addr::ACE_ATM_Addr");
(void) ACE_OS::memset ((void *) &this->atm_addr_,
0,
sizeof this->atm_addr_);
this->init (selector);
}
// Copy constructor.
ACE_ATM_Addr::ACE_ATM_Addr (const ACE_ATM_Addr &sap,
u_char selector)
#if defined (ACE_HAS_FORE_ATM_XTI) || defined (ACE_HAS_FORE_ATM_WS2)
: ACE_Addr (AF_ATM,
#elif defined (ACE_HAS_LINUX_ATM)
: ACE_Addr (PF_ATMSVC,
#else
: ACE_Addr (AF_UNSPEC,
#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 || ACE_HAS_LINUX_ATM */
sizeof this->atm_addr_)
{
ACE_TRACE ("ACE_ATM_Addr::ACE_ATM_Addr");
this->set (sap, selector);
#if defined (ACE_HAS_LINUX_ATM)
this->atm_addr_.sockaddratmsvc.sas_family = PF_ATMSVC;
this->atm_addr_.atmsap.blli[0].l3_proto = ATM_L3_NONE;
this->atm_addr_.atmsap.blli[0].l2_proto = ATM_L2_NONE;
this->atm_addr_.atmsap.bhli.hl_type = ATM_HL_NONE;
#endif /* ACE_HAS_LINUX_ATM */
}
ACE_ATM_Addr::ACE_ATM_Addr (const ATM_Addr *sap,
u_char selector)
#if defined (ACE_HAS_FORE_ATM_XTI) || defined (ACE_HAS_FORE_ATM_WS2)
: ACE_Addr (AF_ATM,
#elif defined (ACE_HAS_LINUX_ATM)
: ACE_Addr (PF_ATMSVC,
#else
: ACE_Addr (AF_UNSPEC,
#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 || ACE_HAS_LINUX_ATM */
sizeof this->atm_addr_)
{
ACE_TRACE ("ACE_ATM_Addr::ACE_ATM_Addr");
this->set (sap, selector);
}
ACE_ATM_Addr::ACE_ATM_Addr (const ACE_TCHAR sap[],
u_char selector)
#if defined (ACE_HAS_FORE_ATM_XTI) || defined (ACE_HAS_FORE_ATM_WS2)
: ACE_Addr (AF_ATM,
#elif defined (ACE_HAS_LINUX_ATM)
: ACE_Addr (PF_ATMSVC,
#else
: ACE_Addr (AF_UNSPEC,
#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 || ACE_HAS_LINUX_ATM */
sizeof this->atm_addr_)
{
ACE_TRACE ("ACE_ATM_Addr::ACE_ATM_Addr");
this->set (sap, selector);
}
ACE_ATM_Addr::~ACE_ATM_Addr (void)
{
}
// Return the address.
void *
ACE_ATM_Addr::get_addr (void) const
{
ACE_TRACE ("ACE_ATM_Addr::get_addr");
return (void *) &this->atm_addr_;
}
void
ACE_ATM_Addr::init (u_char selector)
{
#if defined (ACE_HAS_FORE_ATM_XTI)
// Note: this approach may be FORE implementation-specific. When we
// bind with tag_addr ABSENT and tag_selector PRESENT, only the
// selector (i.e. address[19]) is used by the TP. The rest of the
// local address is filled in by the TP and can be obtained via the
// 'ret' parameter or with t_getname ()/t_getprotaddr ().
atm_addr_.addressType = (u_int16_t) AF_ATM;
atm_addr_.sap.t_atm_sap_addr.SVE_tag_addr = (int8_t) T_ATM_ABSENT;
atm_addr_.sap.t_atm_sap_addr.SVE_tag_selector = (int8_t) T_ATM_PRESENT;
atm_addr_.sap.t_atm_sap_addr.address_format = (u_int8_t) T_ATM_ENDSYS_ADDR;
atm_addr_.sap.t_atm_sap_addr.address_length = ATMNSAP_ADDR_LEN;
atm_addr_.sap.t_atm_sap_addr.address[ATMNSAP_ADDR_LEN - 1] = selector;
atm_addr_.sap.t_atm_sap_layer2.SVE_tag = (int8_t) T_ATM_ABSENT;
atm_addr_.sap.t_atm_sap_layer3.SVE_tag = (int8_t) T_ATM_ABSENT;
atm_addr_.sap.t_atm_sap_appl.SVE_tag = (int8_t) T_ATM_PRESENT;
atm_addr_.sap.t_atm_sap_appl.ID_type = (u_int8_t) T_ATM_USER_APP_ID;
ACE_OS::memcpy (atm_addr_.sap.t_atm_sap_appl.ID.user_defined_ID,
BHLI_MAGIC,
sizeof atm_addr_.sap.t_atm_sap_appl.ID);
#elif defined (ACE_HAS_FORE_ATM_WS2)
ACE_OS::memset ((void *)&atm_addr_, 0, sizeof atm_addr_);
atm_addr_.satm_number.Addr[ ATM_ADDR_SIZE - 1 ] = (char)selector;
atm_addr_.satm_family = AF_ATM;
atm_addr_.satm_number.AddressType = ATM_NSAP;
atm_addr_.satm_number.NumofDigits = ATM_ADDR_SIZE;
atm_addr_.satm_blli.Layer2Protocol = SAP_FIELD_ABSENT;
atm_addr_.satm_blli.Layer3Protocol = SAP_FIELD_ABSENT;
atm_addr_.satm_bhli.HighLayerInfoType = SAP_FIELD_ABSENT;
// Need to know the correspondence.
//atm_addr_.sap.t_atm_sap_appl.SVE_tag = (int8_t) T_ATM_PRESENT;
//atm_addr_.sap.t_atm_sap_appl.ID_type = (u_int8_t) T_ATM_USER_APP_ID;
//ACE_OS::memcpy (atm_addr_.sap.t_atm_sap_appl.ID.user_defined_ID,
// BHLI_MAGIC,
// sizeof atm_addr_.sap.t_atm_sap_appl.ID);
#elif defined (ACE_HAS_LINUX_ATM)
atm_addr_.sockaddratmsvc.sas_family = AF_ATMSVC;
atm_addr_.sockaddratmsvc.sas_addr.prv[ATM_ESA_LEN - 1] = (char)selector;
atm_addr_.atmsap.blli[0].l3_proto = ATM_L3_NONE;
atm_addr_.atmsap.blli[0].l2_proto = ATM_L2_NONE;
atm_addr_.atmsap.bhli.hl_type = ATM_HL_NONE;
#else
ACE_UNUSED_ARG (selector);
#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 || ACE_HAS_LINUX_ATM */
}
int
ACE_ATM_Addr::set (const ACE_ATM_Addr &sap,
u_char selector)
{
ACE_TRACE ("ACE_ATM_Addr::set");
this->init (selector);
this->ACE_Addr::base_set (sap.get_type (),
sap.get_size ());
#if defined (ACE_HAS_FORE_ATM_XTI) || defined (ACE_HAS_FORE_ATM_WS2)
ACE_ASSERT (sap.get_type () == AF_ATM);
#elif defined (ACE_HAS_LINUX_ATM)
ACE_ASSERT (sap.get_type () == PF_ATMSVC);
#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 */
(void) ACE_OS::memcpy ((void *) &this->atm_addr_,
(void *) &sap.atm_addr_,
sizeof this->atm_addr_);
return 0;
}
int
ACE_ATM_Addr::set (const ATM_Addr *sap,
u_char selector)
{
ACE_TRACE ("ACE_ATM_Addr::set");
this->init (selector);
#if defined (ACE_HAS_FORE_ATM_XTI) || defined (ACE_HAS_FORE_ATM_WS2)
this->ACE_Addr::base_set (AF_ATM,
#elif defined (ACE_HAS_LINUX_ATM)
this->ACE_Addr::base_set (PF_ATMSVC,
#else
this->ACE_Addr::base_set (AF_UNSPEC,
#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 */
sizeof (*sap));
(void) ACE_OS::memcpy ((void *) &this->atm_addr_,
(void *) sap,
sizeof this->atm_addr_);
return 0;
}
int
ACE_ATM_Addr::set (const ACE_TCHAR address[],
u_char selector)
{
ACE_TRACE ("ACE_ATM_Addr::set");
int ret;
this->init (selector);
#if defined (ACE_HAS_FORE_ATM_XTI)
atm_addr_.sap.t_atm_sap_addr.SVE_tag_addr =
(int8_t) T_ATM_PRESENT;
#endif /* ACE_HAS_FORE_ATM_XTI */
ret = this -> string_to_addr (address);
this -> set_selector (selector);
return ret;
}
// Transform the string into the current addressing format.
int
ACE_ATM_Addr::string_to_addr (const ACE_TCHAR sap[])
{
ACE_TRACE ("ACE_ATM_Addr::string_to_addr");
#if defined (ACE_HAS_FORE_ATM_XTI) || defined (ACE_HAS_FORE_ATM_WS2)
this->ACE_Addr::base_set (AF_ATM,
#elif defined (ACE_HAS_LINUX_ATM)
this->ACE_Addr::base_set (PF_ATMSVC,
#else
this->ACE_Addr::base_set (AF_UNSPEC,
#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 || ACE_HAS_LINUX_ATM */
sizeof this->atm_addr_);
#if defined (ACE_HAS_FORE_ATM_XTI)
struct hostent *entry;
struct atmnsap_addr *nsap;
// Yow, someone gave us a NULL ATM address!
if (sap == 0)
{
errno = EINVAL;
return -1;
}
else if ((entry = gethostbyname_atmnsap ((ACE_TCHAR *)sap)) != 0)
{
ACE_OS::memcpy (atm_addr_.sap.t_atm_sap_addr.address,
entry->h_addr_list[0],
ATMNSAP_ADDR_LEN - 1);
}
else if ((nsap = atmnsap_addr (sap)) != 0)
{
ACE_OS::memcpy (atm_addr_.sap.t_atm_sap_addr.address,
nsap->atmnsap,
ATMNSAP_ADDR_LEN);
}
else {
errno = EINVAL;
return -1;
}
#elif defined (ACE_HAS_FORE_ATM_WS2)
DWORD dwValue;
HANDLE hLookup;
WSAQUERYSETW qsRestrictions;
CSADDR_INFO csaBuffer;
WCHAR tmpWStr[100];
MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED, sap, -1, tmpWStr, 100);
csaBuffer.LocalAddr.iSockaddrLength = sizeof (struct sockaddr_atm);
csaBuffer.LocalAddr.lpSockaddr = (struct sockaddr *)&atm_addr_;
csaBuffer.RemoteAddr.iSockaddrLength = sizeof (struct sockaddr_atm);
csaBuffer.RemoteAddr.lpSockaddr = (struct sockaddr *)&atm_addr_;
qsRestrictions.dwSize = sizeof (WSAQUERYSETW);
qsRestrictions.lpszServiceInstanceName = 0;
qsRestrictions.lpServiceClassId = &FORE_NAME_CLASS;
qsRestrictions.lpVersion = 0;
qsRestrictions.lpszComment = 0;
qsRestrictions.dwNameSpace = FORE_NAME_SPACE;
qsRestrictions.lpNSProviderId = 0;
qsRestrictions.lpszContext = L"";
qsRestrictions.dwNumberOfProtocols = 0;
qsRestrictions.lpafpProtocols = 0;
qsRestrictions.lpszQueryString = tmpWStr;
qsRestrictions.dwNumberOfCsAddrs = 1;
qsRestrictions.lpcsaBuffer = &csaBuffer;
qsRestrictions.lpBlob = 0; //&blob;
if (::WSALookupServiceBeginW (&qsRestrictions, LUP_RETURN_ALL, &hLookup)
== SOCKET_ERROR) {
ACE_OS::printf ("Error: WSALookupServiceBeginW failed! %d\n",
::WSAGetLastError ());
return -1;
}
dwValue = sizeof (WSAQUERYSETW);
if (::WSALookupServiceNextW (hLookup, 0, &dwValue, &qsRestrictions)
== SOCKET_ERROR) {
if (WSAGetLastError () != WSA_E_NO_MORE) {
ACE_OS::printf ("Error: WSALookupServiceNextW failed! %d\n",
::WSAGetLastError ());
return -1;
}
}
if (WSALookupServiceEnd (hLookup) == SOCKET_ERROR) {
ACE_OS::printf ("Error : WSALookupServiceEnd failed! %d\n",
::WSAGetLastError ());
errno = EINVAL;
return -1;
}
#elif defined (ACE_HAS_LINUX_ATM)
if (sap == 0 || !ACE_OS::strcmp (sap,"")) {
errno = EINVAL;
return -1;
}
if (text2atm ((ACE_TCHAR *)sap,
(struct sockaddr *)& (atm_addr_.sockaddratmsvc),
sizeof (atm_addr_.sockaddratmsvc),
T2A_SVC | T2A_NAME) < 0) {
ACELIB_DEBUG (LM_DEBUG,
"Error : text2atm failed!\n");
errno = EINVAL;
return -1;
}
#else
ACE_UNUSED_ARG (sap);
return 0;
#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 || ACE_HAS_LINUX_ATM */
#if defined (ACE_HAS_FORE_ATM_XTI) || defined (ACE_HAS_FORE_ATM_WS2) || defined (ACE_HAS_LINUX_ATM)
return 0;
#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 */
}
// Transform the current address into string format.
int
ACE_ATM_Addr::addr_to_string (ACE_TCHAR addr[],
size_t addrlen) const
{
ACE_TRACE ("ACE_ATM_Addr::addr_to_string");
#if defined (ACE_HAS_FORE_ATM_XTI)
ACE_TCHAR buffer[MAXNAMELEN + 1];
struct atmnsap_addr nsap;
ACE_OS::memcpy (nsap.atmnsap,
atm_addr_.sap.t_atm_sap_addr.address,
ATMNSAP_ADDR_LEN);
ACE_OS::sprintf (buffer,
ACE_TEXT ("%s"),
atmnsap_ntoa (nsap));
size_t total_len = ACE_OS::strlen (buffer) + sizeof ('\0');
if (addrlen < total_len)
return -1;
else
ACE_OS::strcpy (addr, buffer);
return 0;
#elif defined (ACE_HAS_FORE_ATM_WS2)
ACE_TCHAR buffer[MAXNAMELEN + 1];
int i;
if (addrlen < ATM_ADDR_SIZE + 1)
return -1;
for (i = 0; i < ATM_ADDR_SIZE; i++) {
buffer[ i * 3 ] = '\0';
ACE_OS::sprintf (buffer, ACE_TEXT ("%s%02x."),
buffer,
atm_addr_.satm_number.Addr[ i ]);
}
buffer[ ATM_ADDR_SIZE * 3 - 1 ] = '\0';
ACE_OS::strcpy (addr, buffer);
return 0;
#elif defined (ACE_HAS_LINUX_ATM)
ACE_TCHAR buffer[MAX_ATM_ADDR_LEN + 1];
int total_len;
if ((total_len = atm2text (buffer,
sizeof buffer,
(struct sockaddr *)& (atm_addr_.sockaddratmsvc),
A2T_PRETTY)) < 0) {
ACELIB_DEBUG ((LM_DEBUG,"ACE_ATM_Addr (addr_to_string): atm2text failed\n"));
return -1;
}
if (addrlen < (size_t)total_len)
return -1;
else
ACE_OS::strcpy (addr,
buffer);
return 0;
#else
ACE_UNUSED_ARG (addr);
ACE_UNUSED_ARG (addrlen);
return -1;
#endif /* ACE_HAS_FORE_ATM_XTI && ACE_HAS_FORE_ATM_WS2 */
}
const ACE_TCHAR *
ACE_ATM_Addr::addr_to_string (void) const
{
ACE_TRACE ("ACE_ATM_Addr::addr_to_string");
static ACE_TCHAR addr[MAXHOSTNAMELEN + 1];
if (this->addr_to_string (addr,
MAXHOSTNAMELEN + 1) < 0)
return 0;
return addr;
}
// Set a pointer to the address.
void
ACE_ATM_Addr::set_addr (const void *addr, int len)
{
ACE_TRACE ("ACE_ATM_Addr::set_addr");
#if defined (ACE_HAS_FORE_ATM_XTI) || defined (ACE_HAS_FORE_ATM_WS2)
this->ACE_Addr::base_set (AF_ATM,
#elif defined (ACE_HAS_LINUX_ATM)
this->ACE_Addr::base_set (PF_ATMSVC,
#else
this->ACE_Addr::base_set (AF_UNSPEC,
#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_WS2 */
len);
ACE_OS::memcpy (&this->atm_addr_, addr, len);
}
// Compare two addresses for inequality.
bool
ACE_ATM_Addr::operator != (const ACE_ATM_Addr &sap) const
{
ACE_TRACE ("ACE_ATM_Addr::operator !=");
return ! ((*this) == sap);
}
// Compare two addresses for equality.
bool
ACE_ATM_Addr::operator == (const ACE_ATM_Addr &sap) const
{
ACE_TRACE ("ACE_ATM_Addr::operator ==");
#if defined (ACE_HAS_LINUX_ATM)
return (atm_equal ((const struct sockaddr *)& (this->atm_addr_.sockaddratmsvc),
(const struct sockaddr *)& (sap.atm_addr_.sockaddratmsvc),
0,
0)
&&
sap_equal (& (this->atm_addr_.atmsap),
& (sap.atm_addr_.atmsap),
0));
#else
return ACE_OS::memcmp (&atm_addr_,
&sap.atm_addr_,
sizeof (ATM_Addr)) == 0;
#endif /* ACE_HAS_LINUX_ATM */
}
void
ACE_ATM_Addr::dump (void) const
{
#if defined (ACE_HAS_DUMP)
ACE_TRACE ("ACE_ATM_Addr::dump");
ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
ACE_TCHAR s[ACE_MAX_FULLY_QUALIFIED_NAME_LEN + 16];
ACE_OS::sprintf (s,
ACE_TEXT ("%s"),
this->addr_to_string ());
ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("%s"), s));
ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
#endif /* ACE_HAS_DUMP */
}
ACE_END_VERSIONED_NAMESPACE_DECL
#endif /* ACE_HAS_ATM */

View File

@@ -0,0 +1,195 @@
// -*- C++ -*-
//==========================================================================
/**
* @file ATM_Addr.h
*
* @author Joe Hoffert <joeh@cs.wustl.edu>
*/
//==========================================================================
#ifndef ACE_ATM_ADDR_H
#define ACE_ATM_ADDR_H
#include /**/ "ace/pre.h"
#include /**/ "ace/config-all.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#if defined (ACE_HAS_ATM)
#include /**/ "ace/ACE_export.h"
#include "ace/Addr.h"
#if defined (ACE_HAS_FORE_ATM_XTI)
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
typedef ATMSAPAddress ATM_Addr;
ACE_END_VERSIONED_NAMESPACE_DECL
#elif defined (ACE_HAS_FORE_ATM_WS2)
#define FORE_NAME_SPACE NS_ALL
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
typedef struct sockaddr_atm ATM_Addr;
ACE_END_VERSIONED_NAMESPACE_DECL
#elif defined (ACE_HAS_LINUX_ATM)
#include /**/ "atm.h"
// Open versioned namespace, if enabled by the user.
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
//pbrandao:as Linux has this 2 structs separeted we "link it" here
typedef struct _linux_atm_addr
{
struct sockaddr_atmsvc sockaddratmsvc;
struct atm_sap atmsap;
} ATM_Addr;
#else
typedef int ATM_Addr;
#endif /* ACE_HAS_FORE_ATM_XTI/ACE_HAS_FORE_ATM_WS2/ACE_HAS_LINUX_ATM */
/**
* @class ACE_ATM_Addr
*
* @brief Defines the ATM domain address family address format.
*/
class ACE_Export ACE_ATM_Addr : public ACE_Addr
{
public:
// Constants used for ATM options
static const long LINE_RATE;
static const int OPT_FLAGS_CPID;
static const int OPT_FLAGS_PMP;
static const int DEFAULT_SELECTOR;
// = Initialization methods.
/// Default constructor.
ACE_ATM_Addr (u_char selector = DEFAULT_SELECTOR);
/// Copy constructor.
ACE_ATM_Addr (const ACE_ATM_Addr &,
u_char selector = DEFAULT_SELECTOR);
/**
* Creates an ACE_ATM_Addr from an ATMSAPAddress structure. This
* is vendor specific (FORE systems). May need to change when other
* vendors are supported.
*/
ACE_ATM_Addr (const ATM_Addr *,
u_char selector = DEFAULT_SELECTOR);
/**
* Initializes an ACE_ATM_Addr from the <sap> which can be
* "atm-address" (e.g.,
* "47.0005.80.ffe100.0000.f20f.2200.0020480694f9.00") or "hostname"
* (e.g., "frisbee.cs.wustl.edu").
*/
ACE_ATM_Addr (const ACE_TCHAR sap[],
u_char selector = DEFAULT_SELECTOR);
/// Default dtor.
~ACE_ATM_Addr (void);
// = Initialization methods (useful after object construction).
/// Default initialization for non-address values (e.g.,
/// t_atm_sap_addr.SVE_tag_addr, t_atm_sap_addr.SVE_tag_selector)
void init (u_char selector = DEFAULT_SELECTOR);
/// Initializes from another ACE_ATM_Addr.
int set (const ACE_ATM_Addr &,
u_char selector = DEFAULT_SELECTOR);
/**
* Initializes an ACE_ATM_Addr from an ATMSAPAddress/sockaddr_atm
* structure. This is vendor specific (FORE systems). May need to
* change when other vendors are supported.
*/
int set (const ATM_Addr *,
u_char selector = DEFAULT_SELECTOR);
/**
* Initializes an ACE_ATM_Addr from the <sap> which can be
* "atm-address" (e.g.,
* "47.0005.80.ffe100.0000.f20f.2200.0020480694f9.00") or "hostname"
* (e.g., "frisbee.cs.wustl.edu").
*/
int set (const ACE_TCHAR sap[],
u_char selector = DEFAULT_SELECTOR);
/**
* Initializes an ACE_ATM_Addr from the <sap> which can be
* "atm-address" (e.g.,
* "47.0005.80.ffe100.0000.f20f.2200.0020480694f9.00") or "hostname"
* (e.g., "frisbee.cs.wustl.edu").
*/
virtual int string_to_addr (const ACE_TCHAR sap[]);
/**
* Return the character representation of the ATM address (e.g.,
* "47.0005.80.ffe100.0000.f20f.2200.0020480694f9.00") storing it in
* the @a addr (which is assumed to be <addrlen> bytes long). This
* version is reentrant. Returns -1 if the <addrlen> of the @a addr
* is too small, else 0.
*/
virtual int addr_to_string (ACE_TCHAR addr[],
size_t addrlen) const;
/**
* Return the character representation of the ATM address (e.g.,
* "47.0005.80.ffe100.0000.f20f.2200.0020480694f9.00"). Returns -1
* if the <size> of the <buffer> is too small, else 0.(This version
* is non-reentrant since it returns a pointer to a static data
* area.)
*/
const ACE_TCHAR *addr_to_string (void) const;
/// Return a pointer to the underlying network address.
virtual void *get_addr (void) const;
/// Set a pointer to the address.
virtual void set_addr (const void *, int);
/// Return the selector for network address.
u_char get_selector (void) const;
/// Set the selector for the network address.
void set_selector (u_char selector);
/**
* Compare two addresses for equality. The addresses are considered
* equal if they contain the same ATM address. Q: Is there any
* other check for equality needed for ATM?
*/
bool operator == (const ACE_ATM_Addr &SAP) const;
/// Compare two addresses for inequality.
bool operator != (const ACE_ATM_Addr &SAP) const;
/// Dump the state of an object.
void dump (void) const;
/// Declare the dynamic allocation hooks.
ACE_ALLOC_HOOK_DECLARE;
// char *construct_options (ACE_HANDLE fd,
// int qos_kb,
// int flags,
// long *optsize);
// // Construct options for ATM connections
private:
ATM_Addr atm_addr_;
};
// Close versioned namespace, if enabled by the user.
ACE_END_VERSIONED_NAMESPACE_DECL
#if defined (__ACE_INLINE__)
#include "ace/ATM_Addr.inl"
#endif /* __ACE_INLINE__ */
#endif /* ACE_HAS_ATM */
#include /**/ "ace/post.h"
#endif /* ACE_ATM_ADDR_H */

View File

@@ -0,0 +1,34 @@
// -*- C++ -*-
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
ACE_INLINE u_char
ACE_ATM_Addr::get_selector (void) const
{
ACE_TRACE ("ACE_ATM_Addr::get_selector");
#if defined (ACE_HAS_FORE_ATM_XTI)
return atm_addr_.sap.t_atm_sap_addr.address[ATMNSAP_ADDR_LEN - 1];
#elif defined (ACE_HAS_FORE_ATM_WS2)
return atm_addr_.satm_number.Addr[ ATM_ADDR_SIZE - 1 ];
#elif defined (ACE_HAS_LINUX_ATM)
return atm_addr_.sockaddratmsvc.sas_addr.prv[ATM_ESA_LEN - 1];
#else
return 0;
#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 || ACE_HAS_LINUX_ATM */
}
ACE_INLINE void
ACE_ATM_Addr::set_selector (u_char selector)
{
ACE_TRACE ("ACE_ATM_Addr::set_selector");
#if defined (ACE_HAS_FORE_ATM_XTI)
atm_addr_.sap.t_atm_sap_addr.address[ATMNSAP_ADDR_LEN - 1] = selector;
#elif defined (ACE_HAS_FORE_ATM_WS2)
atm_addr_.satm_number.Addr[ ATM_ADDR_SIZE - 1 ] = selector;
#elif defined (ACE_HAS_LINUX_ATM)
atm_addr_.sockaddratmsvc.sas_addr.prv[ATM_ESA_LEN - 1] = selector;
#else
ACE_UNUSED_ARG (selector);
#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 || ACE_HAS_LINUX_ATM */
}
ACE_END_VERSIONED_NAMESPACE_DECL

View File

@@ -0,0 +1,136 @@
// ATM_Connector.cpp
#include "ace/ATM_Connector.h"
#if defined (ACE_HAS_ATM)
#include "ace/Handle_Set.h"
#if !defined (__ACE_INLINE__)
#include "ace/ATM_Connector.inl"
#endif /* __ACE_INLINE__ */
// Open versioned namespace, if enabled by the user.
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
ACE_ALLOC_HOOK_DEFINE(ACE_ATM_Connector)
ACE_ATM_Connector::ACE_ATM_Connector (void)
{
ACE_TRACE ("ACE_ATM_Connector::ACE_ATM_Connector");
}
// Actively connect and produce a new ACE_ATM_Stream if things go well...
// Connect the <new_stream> to the <remote_sap>, waiting up to
// <timeout> amount of time if necessary.
int
ACE_ATM_Connector::connect (ACE_ATM_Stream &new_stream,
const ACE_ATM_Addr &remote_sap,
ACE_ATM_Params params,
ACE_ATM_QoS options,
ACE_Time_Value *timeout,
const ACE_ATM_Addr &local_sap,
int reuse_addr,
int flags,
int perms)
{
ACE_TRACE ("ACE_ATM_Connector::connect");
#if defined (ACE_HAS_FORE_ATM_XTI)
return connector_.connect(new_stream.get_stream(),
remote_sap,
timeout,
local_sap,
reuse_addr,
flags,
perms,
params.get_device(),
params.get_info(),
params.get_rw_flag(),
params.get_user_data(),
&options.get_qos());
#elif defined (ACE_HAS_FORE_ATM_WS2)
ACELIB_DEBUG(LM_DEBUG,
ACE_TEXT ("ATM_Connector(connect): set QoS parameters\n" ));
ACE_HANDLE s = new_stream.get_handle();
struct sockaddr_atm *saddr = ( struct sockaddr_atm *)remote_sap.get_addr();
ACE_QoS cqos = options.get_qos();
ACE_QoS_Params qos_params = ACE_QoS_Params(0,
0,
&cqos,
0,
0);
ACELIB_DEBUG(LM_DEBUG,
ACE_TEXT ("ATM_Connector(connect): connecting...\n"));
int result = ACE_OS::connect( s,
( struct sockaddr *)saddr,
sizeof( struct sockaddr_atm ),
qos_params );
if ( result != 0 )
ACE_OS::printf( "ATM_Connector(connect): connection failed, %d\n",
::WSAGetLastError());
return result;
#elif defined (ACE_HAS_LINUX_ATM)
ACE_UNUSED_ARG (params);
ACE_UNUSED_ARG (timeout);
ACE_UNUSED_ARG (reuse_addr);
ACE_UNUSED_ARG (perms);
ACE_UNUSED_ARG (flags);
ACE_HANDLE handle = new_stream.get_handle();
ATM_QoS qos =options.get_qos();
ATM_Addr *local_addr=(ATM_Addr*)local_sap.get_addr(),
*remote_addr=(ATM_Addr*)remote_sap.get_addr();
if (ACE_OS::setsockopt(handle,
SOL_ATM,
SO_ATMSAP,
reinterpret_cast<char*> (&(local_addr->atmsap)),
sizeof(local_addr->atmsap)) < 0) {
ACE_OS::printf( "ATM_Connector(connect): unable to set atmsap %d\nContinuing...",
errno);
}
if (ACE_OS::setsockopt(handle,
SOL_ATM,
SO_ATMQOS,
reinterpret_cast<char*> (&qos),
sizeof(qos)) < 0) {
ACELIB_DEBUG((LM_DEBUG,ACE_TEXT ("ATM_Connector(connect): unable to set qos %d\n"),
errno));
return -1;
}
int result = ACE_OS::connect(handle,
(struct sockaddr *)&(remote_addr->sockaddratmsvc),
sizeof( remote_addr->sockaddratmsvc));
if ( result != 0 )
ACELIB_DEBUG(LM_DEBUG,
ACE_TEXT ("ATM_Connector(connect): connection failed, %d\n"),
errno);
return result;
#else
ACE_UNUSED_ARG (new_stream);
ACE_UNUSED_ARG (remote_sap);
ACE_UNUSED_ARG (params);
ACE_UNUSED_ARG (options);
ACE_UNUSED_ARG (timeout);
ACE_UNUSED_ARG (local_sap);
ACE_UNUSED_ARG (reuse_addr);
ACE_UNUSED_ARG (flags);
ACE_UNUSED_ARG (perms);
return 0;
#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 || ACE_HAS_LINUX_ATM */
}
// Close versioned namespace, if enabled by the user.
ACE_END_VERSIONED_NAMESPACE_DECL
#endif /* ACE_HAS_ATM */

View File

@@ -0,0 +1,162 @@
/* -*- C++ -*- */
//=============================================================================
/**
* @file ATM_Connector.h
*
* @author Joe Hoffert <joeh@cs.wustl.edu>
*/
//=============================================================================
#ifndef ACE_ATM_CONNECTOR_H
#define ACE_ATM_CONNECTOR_H
#include /**/ "ace/pre.h"
#include /**/ "ace/config-all.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#if defined (ACE_HAS_ATM)
#include "ace/ATM_Stream.h"
#include "ace/ATM_Params.h"
#include "ace/ATM_QoS.h"
#if defined (ACE_WIN32) || defined (ACE_HAS_LINUX_ATM)
#include "ace/SOCK_Connector.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
typedef ACE_SOCK_Connector ATM_Connector;
ACE_END_VERSIONED_NAMESPACE_DECL
#else
#include "ace/XTI_ATM_Mcast.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
typedef ACE_XTI_ATM_Mcast ATM_Connector;
// Open versioned namespace, if enabled by the user.
ACE_END_VERSIONED_NAMESPACE_DECL
#endif
// Open versioned namespace, if enabled by the user.
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
/**
* @class ACE_ATM_Connector
*
* @brief Defines an active connection factory for the ACE_ATM C++
* wrappers.
*/
class ACE_Export ACE_ATM_Connector
{
public:
// = Initialization methods.
/// Default constructor.
ACE_ATM_Connector (void);
/**
* Actively connect and produce a @a new_stream if things go well.
* The @a remote_sap is the address that we are trying to connect
* with. The <params> are the parameters needed for either socket
* or XTI/ATM connections. The @a timeout is the amount of time to
* wait to connect. If it's 0 then we block indefinitely. If
* *timeout == {0, 0} then the connection is done using non-blocking
* mode. In this case, if the connection can't be made immediately
* the value of -1 is returned with @c errno == EWOULDBLOCK. If
* *timeout > {0, 0} then this is the maximum amount of time to wait before
* timing out. If the time expires before the connection is made
* @c errno == ETIME. The @a local_sap is the value of local address
* to bind to. If it's the default value of <ACE_ATM_Addr::sap_any> then
* the user is letting the OS do the binding. If @a reuse_addr == 1
* then the <local_addr> is reused, even if it hasn't been cleanedup yet.
*/
ACE_ATM_Connector (ACE_ATM_Stream &new_stream,
const ACE_ATM_Addr &remote_sap,
ACE_ATM_Params params = ACE_ATM_Params(),
ACE_ATM_QoS options = ACE_ATM_QoS(),
ACE_Time_Value *timeout = 0,
const ACE_ATM_Addr &local_sap = ACE_ATM_Addr( "", 0 ),
int reuse_addr = 0,
#if defined (ACE_WIN32)
int flags = 0,
#else
int flags = O_RDWR,
#endif /* ACE_WIN32 */
int perms = 0);
/**
* Actively connect and produce a @a new_stream if things go well.
* The @a remote_sap is the address that we are trying to connect
* with. The <params> are the parameters needed for either socket
* or XTI/ATM connections. The @a timeout is the amount of time to
* wait to connect. If it's 0 then we block indefinitely. If
* *timeout == {0, 0} then the connection is done using non-blocking
* mode. In this case, if the connection can't be made immediately
* the value of -1 is returned with @c errno == EWOULDBLOCK. If
* *timeout > {0, 0} then this is the maximum amount of time to wait before
* timing out. If the time expires before the connection is made
* @c errno == ETIME. The @a local_sap is the value of local address
* to bind to. If it's the default value of <ACE_ATM_Addr::sap_any> then
* the user is letting the OS do the binding. If @a reuse_addr == 1
* then the <local_addr> is reused, even if it hasn't been cleanedup yet.
*/
int connect (ACE_ATM_Stream &new_stream,
const ACE_ATM_Addr &remote_sap,
ACE_ATM_Params params = ACE_ATM_Params(),
ACE_ATM_QoS options = ACE_ATM_QoS(),
ACE_Time_Value *timeout = 0,
const ACE_ATM_Addr &local_sap = ACE_ATM_Addr( "",
0 ),
int reuse_addr = 0,
#if defined (ACE_WIN32)
int flags = 0,
#else
int flags = O_RDWR,
#endif /* ACE_WIN32 */
int perms = 0);
/**
* Try to complete a non-blocking connection.
* If connection completion is successful then @a new_stream contains
* the connected ACE_SOCK_Stream. If @a remote_sap is non-NULL then it
* will contain the address of the connected peer.
*/
int complete (ACE_ATM_Stream &new_stream,
ACE_ATM_Addr *remote_sap,
ACE_Time_Value *tv);
/**
* Actively add a leaf to the root (i.e., point-to-multipoint). The
* @a remote_sap is the address of the leaf that we
* are trying to add.
*/
int add_leaf (ACE_ATM_Stream &current_stream,
const ACE_Addr &remote_sap,
ACE_ATM_QoS &qos);
/// Resets any event associations on this handle
bool reset_new_handle (ACE_HANDLE handle);
// = Meta-type info
typedef ACE_ATM_Addr PEER_ADDR;
typedef ACE_ATM_Stream PEER_STREAM;
/// Dump the state of an object.
void dump (void) const;
/// Declare the dynamic allocation hooks.
ACE_ALLOC_HOOK_DECLARE;
private:
ATM_Connector connector_;
};
// Open versioned namespace, if enabled by the user.
ACE_END_VERSIONED_NAMESPACE_DECL
#if defined (__ACE_INLINE__)
#include "ace/ATM_Connector.inl"
#endif /* __ACE_INLINE__ */
#endif /* ACE_HAS_ATM */
#include /**/ "ace/post.h"
#endif /* ACE_ATM_CONNECTOR_H */

View File

@@ -0,0 +1,129 @@
// -*- C++ -*-
// Open versioned namespace, if enabled by the user.
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
ACE_INLINE void
ACE_ATM_Connector::dump (void) const
{
#if defined (ACE_HAS_DUMP)
ACE_TRACE ("ACE_ATM_Connector::dump");
#endif /* ACE_HAS_DUMP */
}
ACE_INLINE
ACE_ATM_Connector::ACE_ATM_Connector (ACE_ATM_Stream &new_stream,
const ACE_ATM_Addr &remote_sap,
ACE_ATM_Params params,
ACE_ATM_QoS options,
ACE_Time_Value *timeout,
const ACE_ATM_Addr &local_sap,
int reuse_addr,
int flags,
int perms)
{
ACE_TRACE ("ACE_ATM_Connector::ACE_ATM_Connector");
if ((ACE_HANDLE)this->connect (new_stream,
remote_sap,
params,
options,
timeout,
local_sap,
reuse_addr,
flags,
perms) == ACE_INVALID_HANDLE
&& timeout != 0 && !(errno == EWOULDBLOCK || errno == ETIME))
ACELIB_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"),
ACE_TEXT ("ACE_ATM_Stream::ACE_ATM_Stream")));
}
// Try to complete a non-blocking connection.
ACE_INLINE
int
ACE_ATM_Connector::complete (ACE_ATM_Stream &new_stream,
ACE_ATM_Addr *remote_sap,
ACE_Time_Value *tv)
{
ACE_TRACE ("ACE_ATM_Connector::complete");
#if defined (ACE_HAS_ATM)
return connector_.complete(new_stream.get_stream(),
remote_sap,
tv);
#else
ACE_UNUSED_ARG(new_stream);
ACE_UNUSED_ARG(remote_sap);
ACE_UNUSED_ARG(tv);
return 0;
#endif
}
ACE_INLINE
int
ACE_ATM_Connector::add_leaf (ACE_ATM_Stream &current_stream,
const ACE_Addr &remote_sap,
ACE_ATM_QoS &qos)
{
ACE_TRACE ("ACE_ATM_Connector::add_leaf");
#if defined (ACE_HAS_FORE_ATM_XTI)
return connector_.add_leaf(current_stream.get_stream(),
remote_sap,
leaf_id,
timeout);
#elif defined (ACE_HAS_FORE_ATM_WS2)
struct sockaddr_atm *saddr = (struct sockaddr_atm *)remote_sap.get_addr();
ACE_QoS cqos = qos.get_qos();
int addr_len = sizeof( struct sockaddr_atm );
ACE_QoS_Params qos_params(0,
0,
&cqos,
0,
(JL_SENDER_ONLY));
ACE_OS::printf( "ATM_Connector::add_leaf: connecting...\n" );
ACE_HANDLE result = ACE_OS::join_leaf(current_stream.get_handle(),
(struct sockaddr *)saddr,
addr_len,
qos_params);
if ( result == ACE_INVALID_HANDLE )
ACE_OS::printf( "ATM_Connector(add_leaf): connection failed, %d\n",
::WSAGetLastError());
return (result != ACE_INVALID_HANDLE);
#elif defined (ACE_HAS_LINUX_ATM)
ACE_OS::printf("ATM_Connector(add_leaf): not yet implemented in Linux\n");
ACE_UNUSED_ARG(current_stream);
ACE_UNUSED_ARG(remote_sap);
ACE_UNUSED_ARG(leaf_id);
ACE_UNUSED_ARG(timeout);
return 0;
#else
ACE_UNUSED_ARG(current_stream);
ACE_UNUSED_ARG(remote_sap);
ACE_UNUSED_ARG(leaf_id);
ACE_UNUSED_ARG(timeout);
return 0;
#endif
}
ACE_INLINE
bool
ACE_ATM_Connector::reset_new_handle (ACE_HANDLE handle)
{
#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
// Reset the event association
return ::WSAEventSelect ((SOCKET) handle,
0,
0);
#else /* !defined ACE_HAS_WINSOCK2 */
ACE_UNUSED_ARG (handle);
return false;
#endif /* ACE_WIN32 */
}
// Close versioned namespace, if enabled by the user.
ACE_END_VERSIONED_NAMESPACE_DECL

View File

@@ -0,0 +1,18 @@
#include "ace/ATM_Params.h"
#if defined (ACE_HAS_ATM)
#if !defined (__ACE_INLINE__)
#include "ace/ATM_Params.inl"
#endif /* __ACE_INLINE__ */
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
ACE_ALLOC_HOOK_DEFINE(ACE_ATM_Params)
ACE_END_VERSIONED_NAMESPACE_DECL
#endif /* ACE_HAS_ATM */

View File

@@ -0,0 +1,212 @@
// -*- C++ -*-
//==========================================================================
/**
* @file ATM_Params.h
*
* @author Joe Hoffert <joeh@cs.wustl.edu>
*/
//==========================================================================
#ifndef ACE_ATM_PARAMS_H
#define ACE_ATM_PARAMS_H
#include /**/ "ace/pre.h"
#include /**/ "ace/config-all.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#if defined (ACE_HAS_ATM)
#include /**/ "ace/ACE_export.h"
#if defined (ACE_HAS_FORE_ATM_XTI)
#include "ace/TLI.h"
#define ATM_PROTOCOL_DEFAULT 0
typedef struct t_info Param_Info;
typedef struct netbuf Param_Udata;
#elif defined (ACE_HAS_FORE_ATM_WS2)
#include "ace/SOCK.h"
#define ATM_PROTOCOL_DEFAULT ATMPROTO_AAL5
#define ACE_XTI_ATM_DEVICE ""
typedef int Param_Info;
typedef int Param_Udata;
#elif defined (ACE_HAS_LINUX_ATM)
#include /**/ "atm.h"
#define AF_ATM PF_ATMSVC
#define ACE_XTI_ATM_DEVICE ""
#define ATM_PROTOCOL_DEFAULT ATM_AAL5
typedef int Param_Info;
typedef int Param_Udata;
#else
#define ACE_XTI_ATM_DEVICE ""
typedef int Param_Info;
typedef int Param_Udata;
#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 || ACE_HAS_LINUX_ATM */
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
/**
* @class ACE_ATM_Params
*
* @brief Wrapper class that simplifies the information passed to the ATM
* enabled ACE_ATM_Connector class.
*/
class ACE_Export ACE_ATM_Params
{
public:
/**
* Initialize the data members. This class combines options from
* ACE_SOCK_Connector (@a protocol_family, @a protocol, <type>,
* @a protocol_info, <group>, and @a flags) and
* ACE_TLI_Connector (<device>, <info>, <rw_flag>, <oflag>, and <udata>)
* so that either mechanism can be used transparently for ATM.
*/
ACE_ATM_Params (int rw_flag = 1,
const char device[] = ACE_XTI_ATM_DEVICE,
Param_Info *info = 0,
Param_Udata *udata = 0,
int oflag = O_RDWR,
int protocol_family = AF_ATM,
int protocol = ATM_PROTOCOL_DEFAULT,
int type =
#if defined (ACE_HAS_LINUX_ATM)
SOCK_DGRAM,
#else
SOCK_RAW,
#endif /* ACE_HAS_LINUX_ATM */
ACE_Protocol_Info *protocol_info = 0,
ACE_SOCK_GROUP g = 0,
u_long flags
= ACE_FLAG_MULTIPOINT_C_ROOT
| ACE_FLAG_MULTIPOINT_D_ROOT, // connector by default
int reuse_addr = 0);
/// Destructor.
~ACE_ATM_Params ();
/// Get protocol family.
int get_protocol_family (void) const;
/// Set protocol family.
void set_protocol_family (int);
/// Get protocol.
int get_protocol (void) const;
/// Set protocol.
void set_protocol (int);
/// Get type.
int get_type (void) const;
/// Set type.
void set_type (int);
/// Get protocol info.
ACE_Protocol_Info *get_protocol_info( void );
/// Set protocol info.
void set_protocol_info( ACE_Protocol_Info *);
/// Get socket group.
ACE_SOCK_GROUP get_sock_group( void );
/// Set socket group.
void set_sock_group( ACE_SOCK_GROUP );
/// Get socket flags.
u_long get_flags( void );
/// Set socket flags.
void set_flags( u_long );
/// Get reuse_addr flag.
int get_reuse_addr (void) const;
/// Set reuse_addr flag.
void set_reuse_addr (int);
/// Get device.
const char* get_device (void) const;
/// Get info.
Param_Info* get_info (void) const;
/// Set info.
void set_info (Param_Info *);
/// Get r/w flag.
int get_rw_flag (void) const;
/// Set r/w flag.
void set_rw_flag (int);
/// Get user data.
Param_Udata* get_user_data (void) const;
/// Set user data.
void set_user_data (Param_Udata*);
/// Get open flag.
int get_oflag (void) const;
/// Set open flag.
void set_oflag (int);
/// Dump the state of an object.
void dump (void) const;
/// Declare the dynamic allocation hooks.
ACE_ALLOC_HOOK_DECLARE;
private:
/// Protocol family for sockets connections.
int protocol_family_;
/// Protocol for sockets connections.
int protocol_;
/// Type for opening sockets.
int type_;
/// Information about the protocol.
ACE_Protocol_Info *protocol_info_;
/// Socket group used (for sockets only).
ACE_SOCK_GROUP group_;
/// Flags for sockets (for sockets only).
u_long flags_;
/// Flag for reusing address for opening sockets.
int reuse_addr_;
/// Device name for XTI/ATM connections.
const char *device_;
/// Info for XTI/ATM connections.
Param_Info *info_;
/// R/W flag for XTI/ATM connections.
int rw_flag_;
/// User data for XTI/ATM connections.
Param_Udata *udata_;
/// Open flag for XTI/ATM connections.
int oflag_;
};
ACE_END_VERSIONED_NAMESPACE_DECL
#if defined (__ACE_INLINE__)
#include "ace/ATM_Params.inl"
#endif /* __ACE_INLINE__ */
#endif /* ACE_HAS_ATM */
#include /**/ "ace/post.h"
#endif /* ACE_ATM_PARAMS_H */

View File

@@ -0,0 +1,232 @@
// -*- C++ -*-
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
ACE_INLINE void
ACE_ATM_Params::dump (void) const
{
#if defined (ACE_HAS_DUMP)
ACE_TRACE ("ACE_ATM_Params::dump");
#endif /* ACE_HAS_DUMP */
}
ACE_INLINE
ACE_ATM_Params::ACE_ATM_Params (int rw_flag,
const char device[],
Param_Info *info,
Param_Udata *udata,
int oflag,
int protocol_family,
int protocol,
int type,
ACE_Protocol_Info *protocol_info,
ACE_SOCK_GROUP g,
u_long flags,
int reuse_addr)
: protocol_family_(protocol_family),
protocol_(protocol),
type_(type),
protocol_info_(protocol_info),
group_(g),
flags_(flags),
reuse_addr_(reuse_addr),
device_(device),
info_(info),
rw_flag_(rw_flag),
udata_(udata),
oflag_(oflag)
{
ACE_TRACE ("ACE_ATM_Params::ACE_ATM_Params");
}
// Default dtor.
ACE_INLINE
ACE_ATM_Params::~ACE_ATM_Params (void)
{
ACE_TRACE ("ACE_ATM_Params::~ACE_ATM_Params");
}
ACE_INLINE
int
ACE_ATM_Params::get_protocol_family (void) const
{
ACE_TRACE ("ACE_ATM_Params::get_protocol_family");
return protocol_family_;
}
ACE_INLINE
void
ACE_ATM_Params::set_protocol_family (int family)
{
ACE_TRACE ("ACE_ATM_Params::set_protocol_family");
protocol_family_ = family;
}
ACE_INLINE
int
ACE_ATM_Params::get_protocol (void) const
{
ACE_TRACE ("ACE_ATM_Params::get_protocol");
return protocol_;
}
ACE_INLINE
void
ACE_ATM_Params::set_protocol (int protocol)
{
ACE_TRACE ("ACE_ATM_Params::set_protocol");
protocol_ = protocol;
}
ACE_INLINE
int
ACE_ATM_Params::get_type (void) const
{
ACE_TRACE ("ACE_ATM_Params::get_type");
return type_;
}
ACE_INLINE
void
ACE_ATM_Params::set_type (int type)
{
ACE_TRACE ("ACE_ATM_Params::set_type");
type_ = type;
}
ACE_INLINE
ACE_Protocol_Info*
ACE_ATM_Params::get_protocol_info( void )
{
ACE_TRACE ("ACE_ATM_Params::get_protocol_info");
return protocol_info_;
}
ACE_INLINE
void
ACE_ATM_Params::set_protocol_info( ACE_Protocol_Info *protocol_info )
{
ACE_TRACE ("ACE_ATM_Params::set_protocol_info");
protocol_info_ = protocol_info;
}
ACE_INLINE
ACE_SOCK_GROUP
ACE_ATM_Params::get_sock_group( void )
{
ACE_TRACE ("ACE_ATM_Params::get_sock_group");
return group_;
}
ACE_INLINE
void
ACE_ATM_Params::set_sock_group( ACE_SOCK_GROUP g )
{
ACE_TRACE ("ACE_ATM_Params::set_sock_group");
group_ = g;
}
ACE_INLINE
u_long
ACE_ATM_Params::get_flags( void )
{
ACE_TRACE ("ACE_ATM_Params::get_flags");
return flags_;
}
ACE_INLINE
void
ACE_ATM_Params::set_flags( u_long flags)
{
ACE_TRACE ("ACE_ATM_Params::set_flags");
flags_ = flags;
}
ACE_INLINE
int
ACE_ATM_Params::get_reuse_addr (void) const
{
ACE_TRACE ("ACE_ATM_Params::get_reuse_addr");
return reuse_addr_;
}
ACE_INLINE
void
ACE_ATM_Params::set_reuse_addr (int reuse_addr)
{
ACE_TRACE ("ACE_ATM_Params::set_reuse_addr");
reuse_addr_ = reuse_addr;
}
ACE_INLINE
const char*
ACE_ATM_Params::get_device (void) const
{
ACE_TRACE ("ACE_ATM_Params::get_device");
return device_;
}
ACE_INLINE
Param_Info*
ACE_ATM_Params::get_info (void) const
{
ACE_TRACE ("ACE_ATM_Params::get_info");
return info_;
}
ACE_INLINE
void
ACE_ATM_Params::set_info (Param_Info* info)
{
ACE_TRACE ("ACE_ATM_Params::set_info");
info_ = info;
}
ACE_INLINE
int
ACE_ATM_Params::get_rw_flag (void) const
{
ACE_TRACE ("ACE_ATM_Params::get_rw_flag");
return rw_flag_;
}
ACE_INLINE
void
ACE_ATM_Params::set_rw_flag (int rw_flag)
{
ACE_TRACE ("ACE_ATM_Params::set_rw_flag");
rw_flag_ = rw_flag;
}
ACE_INLINE
Param_Udata*
ACE_ATM_Params::get_user_data (void) const
{
ACE_TRACE ("ACE_ATM_Params::get_user_data");
return udata_;
}
ACE_INLINE
void
ACE_ATM_Params::set_user_data (Param_Udata *udata)
{
ACE_TRACE ("ACE_ATM_Params::set_user_data");
udata_ = udata;
}
ACE_INLINE
int
ACE_ATM_Params::get_oflag (void) const
{
ACE_TRACE ("ACE_ATM_Params::get_oflag");
return oflag_;
}
ACE_INLINE
void
ACE_ATM_Params::set_oflag (int oflag)
{
ACE_TRACE ("ACE_ATM_Params::set_oflag");
oflag_ = oflag;
}
ACE_END_VERSIONED_NAMESPACE_DECL

View File

@@ -0,0 +1,629 @@
#include "ace/ATM_QoS.h"
#if defined (ACE_HAS_ATM)
#if !defined (__ACE_INLINE__)
#include "ace/ATM_QoS.inl"
#endif /* __ACE_INLINE__ */
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
#if defined (ACE_HAS_FORE_ATM_XTI) || defined (ACE_HAS_FORE_ATM_WS2)
#define BHLI_MAGIC "FORE_ATM"
// This is line rate in cells/s for an OC-3 MM interface.
const long ACE_ATM_QoS::LINE_RATE = 353207;
const int ACE_ATM_QoS::OPT_FLAGS_CPID = 0x1;
const int ACE_ATM_QoS::OPT_FLAGS_PMP = 0x2;
const int ACE_ATM_QoS::DEFAULT_SELECTOR = 0x99;
const int ACE_ATM_QoS::DEFAULT_PKT_SIZE = 8192;
#elif defined (ACE_HAS_LINUX_ATM)
//pbrandao:for Linux:
//pbrandao:for now stick with current definitions
//pbrandao:see if later need to change
const long ACE_ATM_QoS::LINE_RATE = 353207;
const int ACE_ATM_QoS::OPT_FLAGS_CPID = 0x1;
const int ACE_ATM_QoS::OPT_FLAGS_PMP = 0x2;
const int ACE_ATM_QoS::DEFAULT_SELECTOR = 0x99;
const int ACE_ATM_QoS::DEFAULT_PKT_SIZE = 8192;
#else
const long ACE_ATM_QoS::LINE_RATE = 0L;
const int ACE_ATM_QoS::OPT_FLAGS_CPID = 0;
const int ACE_ATM_QoS::OPT_FLAGS_PMP = 0;
const int ACE_ATM_QoS::DEFAULT_SELECTOR = 0x0;
const int ACE_ATM_QoS::DEFAULT_PKT_SIZE = 0;
#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 || ACE_HAS_LINUX_ATM */
ACE_ALLOC_HOOK_DEFINE(ACE_ATM_QoS)
ACE_ATM_QoS::ACE_ATM_QoS (int pktSize)
{
ACE_TRACE ("ACE_ATM_QoS::ACE_ATM_QoS");
#if defined (ACE_HAS_LINUX_ATM)
ACE_OS::memset(&qos_, 0, sizeof(qos_));
qos_.aal = ATM_PROTOCOL_DEFAULT;
qos_.rxtp.traffic_class = ATM_ANYCLASS;
qos_.rxtp.max_sdu = pktSize;
qos_.txtp.traffic_class = ATM_ANYCLASS;
qos_.txtp.max_sdu = pktSize;
#else
ACE_UNUSED_ARG (pktSize);
#endif /* ACE_HAS_LINUX_ATM */
}
ACE_ATM_QoS::ACE_ATM_QoS(int rate,
int pktSize)
{
ACE_TRACE( "ACE_ATM_QoS::ACE_ATM_QoS" );
#if defined (ACE_HAS_FORE_ATM_WS2)
AAL_PARAMETERS_IE ie_aalparams;
ATM_TRAFFIC_DESCRIPTOR_IE ie_td;
ATM_BROADBAND_BEARER_CAPABILITY_IE ie_bbc;
ATM_QOS_CLASS_IE ie_qos;
Q2931_IE *ie_ptr;
int size;
// Setting up cbr parameters ...
ie_aalparams.AALType = AALTYPE_5;
ie_aalparams.AALSpecificParameters.AAL5Parameters.ForwardMaxCPCSSDUSize
= pktSize; // was 1516;
ie_aalparams.AALSpecificParameters.AAL5Parameters.BackwardMaxCPCSSDUSize
= pktSize; // was 1516;
ie_aalparams.AALSpecificParameters.AAL5Parameters.Mode = AAL5_MODE_MESSAGE;
ie_aalparams.AALSpecificParameters.AAL5Parameters.SSCSType = AAL5_SSCS_NULL;
size = sizeof(Q2931_IE_TYPE) + sizeof(ULONG) + sizeof(AAL_PARAMETERS_IE);
ie_td.Forward.PeakCellRate_CLP0 = SAP_FIELD_ABSENT;
ie_td.Forward.PeakCellRate_CLP01 = rate;
ie_td.Forward.SustainableCellRate_CLP0 = SAP_FIELD_ABSENT;
ie_td.Forward.SustainableCellRate_CLP01 = SAP_FIELD_ABSENT;
ie_td.Forward.MaxBurstSize_CLP0 = SAP_FIELD_ABSENT;
ie_td.Forward.MaxBurstSize_CLP01 = SAP_FIELD_ABSENT;
ie_td.Forward.Tagging = SAP_FIELD_ABSENT;
ie_td.Backward.PeakCellRate_CLP0 = SAP_FIELD_ABSENT;
ie_td.Backward.PeakCellRate_CLP01 = rate;
ie_td.Backward.SustainableCellRate_CLP0 = SAP_FIELD_ABSENT;
ie_td.Backward.SustainableCellRate_CLP01 = SAP_FIELD_ABSENT;
ie_td.Backward.MaxBurstSize_CLP0 = SAP_FIELD_ABSENT;
ie_td.Backward.MaxBurstSize_CLP01 = SAP_FIELD_ABSENT;
ie_td.Backward.Tagging = SAP_FIELD_ABSENT;
ie_td.BestEffort = 0; // Note: this must be set to zero for CBR.
size += sizeof( Q2931_IE_TYPE )
+ sizeof( ULONG )
+ sizeof( ATM_TRAFFIC_DESCRIPTOR_IE );
ie_bbc.BearerClass = BCOB_X;
ie_bbc.TrafficType = TT_CBR;
ie_bbc.TimingRequirements = TR_END_TO_END;
ie_bbc.ClippingSusceptability = CLIP_NOT;
ie_bbc.UserPlaneConnectionConfig = UP_P2P;
size += sizeof( Q2931_IE_TYPE )
+ sizeof( ULONG )
+ sizeof( ATM_BROADBAND_BEARER_CAPABILITY_IE );
ie_qos.QOSClassForward = QOS_CLASS1;
ie_qos.QOSClassBackward = QOS_CLASS1; // This may not be really used
// since we do only simplex data xfer.
size += sizeof(Q2931_IE_TYPE) + sizeof(ULONG) + sizeof(ATM_QOS_CLASS_IE);
qos_.ProviderSpecific.buf = (char *) ACE_OS::malloc(size);
if (qos_.ProviderSpecific.buf == 0) {
ACELIB_ERROR((LM_ERROR,
ACE_TEXT ("ACE_ATM_QoS::ACE_ATM_QoS: Unable to allocate %d bytes for qos_.ProviderSpecific.buf\n"),
size));
return;
}
qos_.ProviderSpecific.len = size;
ACE_OS::memset(qos_.ProviderSpecific.buf, 0, size);
ie_ptr = (Q2931_IE *) qos_.ProviderSpecific.buf;
ie_ptr->IEType = IE_AALParameters;
ie_ptr->IELength = sizeof( Q2931_IE_TYPE )
+ sizeof( ULONG )
+ sizeof( AAL_PARAMETERS_IE );
ACE_OS::memcpy(ie_ptr->IE, &ie_aalparams, sizeof(AAL_PARAMETERS_IE));
ie_ptr = (Q2931_IE *) ((char *)ie_ptr + ie_ptr->IELength);
ie_ptr->IEType = IE_TrafficDescriptor;
ie_ptr->IELength = sizeof( Q2931_IE_TYPE )
+ sizeof( ULONG )
+ sizeof( ATM_TRAFFIC_DESCRIPTOR_IE );
ACE_OS::memcpy(ie_ptr->IE, &ie_td, sizeof(ATM_TRAFFIC_DESCRIPTOR_IE));
ie_ptr = (Q2931_IE *) ((char *)ie_ptr + ie_ptr->IELength);
ie_ptr->IEType = IE_BroadbandBearerCapability;
ie_ptr->IELength = sizeof( Q2931_IE_TYPE )
+ sizeof( ULONG )
+ sizeof( ATM_BROADBAND_BEARER_CAPABILITY_IE );
ACE_OS::memcpy(ie_ptr->IE,
&ie_bbc,
sizeof(ATM_BROADBAND_BEARER_CAPABILITY_IE));
ie_ptr = (Q2931_IE *) ((char *)ie_ptr + ie_ptr->IELength);
ie_ptr->IEType = IE_QOSClass;
ie_ptr->IELength = sizeof( Q2931_IE_TYPE )
+ sizeof( ULONG )
+ sizeof( ATM_QOS_CLASS_IE );
ACE_OS::memcpy(ie_ptr->IE, &ie_qos, sizeof(ATM_QOS_CLASS_IE));
// qos_.SendingFlowspec.TokenRate = 0xffffffff;
// qos_.SendingFlowspec.TokenBucketSize = 0xffffffff;
// qos_.SendingFlowspec.PeakBandwidth = 0xffffffff;
// qos_.SendingFlowspec.Latency = 0xffffffff;
// qos_.SendingFlowspec.DelayVariation = 0xffffffff;
// qos_.SendingFlowspec.ServiceType = SERVICETYPE_BESTEFFORT;
// This will most probably be ignored by the service provider.
// qos_.SendingFlowspec.MaxSduSize = 0xffffffff;
// qos_.SendingFlowspec.MinimumPolicedSize = 0xffffffff;
// qos_.ReceivingFlowspec.TokenRate = 0xffffffff;
// qos_.ReceivingFlowspec.TokenBucketSize = 0xffffffff;
// qos_.ReceivingFlowspec.PeakBandwidth = 0xffffffff;
// qos_.ReceivingFlowspec.Latency = 0xffffffff;
// qos_.ReceivingFlowspec.DelayVariation = 0xffffffff;
// qos_.ReceivingFlowspec.ServiceType = SERVICETYPE_BESTEFFORT;
// This will most probably be ignored by the service provider.
// qos_.ReceivingFlowspec.MaxSduSize = 0xffffffff;
// qos_.ReceivingFlowspec.MinimumPolicedSize = 0;
ACE_Flow_Spec send_fspec( 0xffffffff,
0xffffffff,
0xffffffff,
0xffffffff,
0xffffffff,
SERVICETYPE_BESTEFFORT,
// This will most probably ignored by SP.
0xffffffff,
0xffffffff,
15,
ACE_DEFAULT_THREAD_PRIORITY ),
recv_fspec( 0xffffffff,
0xffffffff,
0xffffffff,
0xffffffff,
0xffffffff,
SERVICETYPE_BESTEFFORT,
// This will most probably ignored by SP.
0xffffffff,
0,
15,
ACE_DEFAULT_THREAD_PRIORITY );
qos_.sending_flowspec (send_fspec);
qos_.receiving_flowspec (recv_fspec);
#elif defined (ACE_HAS_FORE_ATM_XTI)
ACE_UNUSED_ARG (rate);
ACE_UNUSED_ARG (pktSize);
#elif defined (ACE_HAS_LINUX_ATM)
ACE_OS::memset(&qos_,
0,
sizeof(qos_));
qos_.aal = ATM_PROTOCOL_DEFAULT;
qos_.rxtp.max_sdu = pktSize;
if (rate > 0) {
qos_.rxtp.pcr = rate;
qos_.rxtp.traffic_class = ATM_CBR;
qos_.txtp.traffic_class = ATM_CBR;
qos_.txtp.pcr = rate;
}
else {
qos_.rxtp.traffic_class = ATM_UBR;
qos_.txtp.traffic_class = ATM_UBR;
}
qos_.txtp.max_sdu = pktSize;
#else
ACE_UNUSED_ARG (rate);
#endif /* ACE_HAS_FORE_ATM_WS2 || ACE_HAS_FORE_ATM_XTI || ACE_HAS_LINUX_ATM */
}
void
ACE_ATM_QoS::set_cbr_rate (int rate,
int pktSize)
{
ACE_TRACE ("ACE_ATM_QoS::set_cbr_rate");
#if defined (ACE_HAS_FORE_ATM_WS2)
/*
AAL_PARAMETERS_IE ie_aalparams;
ATM_TRAFFIC_DESCRIPTOR_IE ie_td;
ATM_BROADBAND_BEARER_CAPABILITY_IE ie_bbc;
ATM_QOS_CLASS_IE ie_qos;
Q2931_IE *ie_ptr;
int size;
*/
ACE_OS::printf( "ATM_QoS(set_cbr_rate): set rate to %d c/s\n", rate );
// Setting up cbr parameters ...
/*
FORE has changed this - we no longer specify QoS this way
ie_aalparams.AALType = AALTYPE_5;
ie_aalparams.AALSpecificParameters.AAL5Parameters.ForwardMaxCPCSSDUSize
= pktSize; // was 1516;
ie_aalparams.AALSpecificParameters.AAL5Parameters.BackwardMaxCPCSSDUSize
= pktSize; // was 1516;
ie_aalparams.AALSpecificParameters.AAL5Parameters.Mode = AAL5_MODE_MESSAGE;
ie_aalparams.AALSpecificParameters.AAL5Parameters.SSCSType = AAL5_SSCS_NULL;
size = sizeof(Q2931_IE_TYPE) + sizeof(ULONG) + sizeof(AAL_PARAMETERS_IE);
ie_td.Forward.PeakCellRate_CLP0 = SAP_FIELD_ABSENT;
ie_td.Forward.PeakCellRate_CLP01 = rate;
ie_td.Forward.SustainableCellRate_CLP0 = SAP_FIELD_ABSENT;
ie_td.Forward.SustainableCellRate_CLP01 = SAP_FIELD_ABSENT;
ie_td.Forward.MaxBurstSize_CLP0 = SAP_FIELD_ABSENT;
ie_td.Forward.MaxBurstSize_CLP01 = SAP_FIELD_ABSENT;
ie_td.Forward.Tagging = SAP_FIELD_ABSENT;
ie_td.Backward.PeakCellRate_CLP0 = SAP_FIELD_ABSENT;
ie_td.Backward.PeakCellRate_CLP01 = rate;
ie_td.Backward.SustainableCellRate_CLP0 = SAP_FIELD_ABSENT;
ie_td.Backward.SustainableCellRate_CLP01 = SAP_FIELD_ABSENT;
ie_td.Backward.MaxBurstSize_CLP0 = SAP_FIELD_ABSENT;
ie_td.Backward.MaxBurstSize_CLP01 = SAP_FIELD_ABSENT;
ie_td.Backward.Tagging = SAP_FIELD_ABSENT;
ie_td.BestEffort = 0; // Note: this must be set to zero for CBR.
size += sizeof( Q2931_IE_TYPE ) +
sizeof( ULONG ) +
sizeof( ATM_TRAFFIC_DESCRIPTOR_IE );
ie_bbc.BearerClass = BCOB_X;
ie_bbc.TrafficType = TT_CBR;
ie_bbc.TimingRequirements = TR_END_TO_END;
ie_bbc.ClippingSusceptability = CLIP_NOT;
ie_bbc.UserPlaneConnectionConfig = UP_P2P;
size += sizeof(Q2931_IE_TYPE) +
sizeof(ULONG) +
sizeof(ATM_BROADBAND_BEARER_CAPABILITY_IE);
ie_qos.QOSClassForward = QOS_CLASS1;
ie_qos.QOSClassBackward = QOS_CLASS1; // This may not be really used
// since we only simplex data xfer.
size += sizeof(Q2931_IE_TYPE) + sizeof(ULONG) + sizeof(ATM_QOS_CLASS_IE);
qos_.ProviderSpecific.buf = (char *) ACE_OS::malloc(size);
if (qos_.ProviderSpecific.buf == 0) {
ACELIB_ERROR((LM_ERROR,
ACE_TEXT ("ACE_ATM_QoS::ACE_ATM_QoS: Unable to allocate %d bytes for qos_.ProviderSpecific.buf\n"),
size));
return;
}
qos_.ProviderSpecific.len = size;
ACE_OS::memset(qos_.ProviderSpecific.buf, 0, size);
ie_ptr = (Q2931_IE *) qos_.ProviderSpecific.buf;
ie_ptr->IEType = IE_AALParameters;
ie_ptr->IELength = sizeof( Q2931_IE_TYPE ) +
sizeof( ULONG ) +
sizeof( AAL_PARAMETERS_IE );
ACE_OS::memcpy(ie_ptr->IE, &ie_aalparams, sizeof(AAL_PARAMETERS_IE));
ie_ptr = (Q2931_IE *) ((char *)ie_ptr + ie_ptr->IELength);
ie_ptr->IEType = IE_TrafficDescriptor;
ie_ptr->IELength = sizeof( Q2931_IE_TYPE ) +
sizeof( ULONG ) +
sizeof( ATM_TRAFFIC_DESCRIPTOR_IE );
ACE_OS::memcpy(ie_ptr->IE, &ie_td, sizeof(ATM_TRAFFIC_DESCRIPTOR_IE));
ie_ptr = (Q2931_IE *) ((char *)ie_ptr + ie_ptr->IELength);
ie_ptr->IEType = IE_BroadbandBearerCapability;
ie_ptr->IELength = sizeof( Q2931_IE_TYPE ) +
sizeof( ULONG ) +
sizeof( ATM_BROADBAND_BEARER_CAPABILITY_IE );
ACE_OS::memcpy( ie_ptr->IE,
&ie_bbc,
sizeof( ATM_BROADBAND_BEARER_CAPABILITY_IE ));
ie_ptr = (Q2931_IE *) ((char *)ie_ptr + ie_ptr->IELength);
ie_ptr->IEType = IE_QOSClass;
ie_ptr->IELength = sizeof(Q2931_IE_TYPE) + sizeof(ULONG) +
sizeof(ATM_QOS_CLASS_IE);
ACE_OS::memcpy(ie_ptr->IE, &ie_qos, sizeof(ATM_QOS_CLASS_IE));
*/
const int BYTES_PER_ATM_CELL = 53;
ACE_OS::memset(&qos_, 0, sizeof(ATM_QoS));
// Setting the token rate sets the minimum rate. 3 Mbits/sec seems too high.
// Certainly for Vaudeville audio, we only need about 1000 c/s which is
// 424000 bits/sec which is 53000 bytes/sec.
//qos_.SendingFlowspec.TokenRate = 3*(1024*128); // 3Mbits/sec
qos_.SendingFlowspec.TokenRate = 53000; // 1000 cells/sec
qos_.SendingFlowspec.TokenBucketSize = 32*1024; // our block size
//ourQos.SendingFlowspec.PeakBandwidth = ourQos.SendingFlowspec.TokenRate;
qos_.SendingFlowspec.ServiceType = SERVICETYPE_GUARANTEED;
// Peak bandwidth is in bytes/sec. The rate is specified in cells/sec so
// we need to convert from cells/sec to bytes/sec (i.e., multiply by 53).
qos_.SendingFlowspec.PeakBandwidth = rate * BYTES_PER_ATM_CELL;
qos_.SendingFlowspec.Latency = -1; // we don't care too much
qos_.SendingFlowspec.DelayVariation = -1; // we don't care too much
// no provider-specific data allowed on ATM
qos_.ProviderSpecific.buf=0;
qos_.ProviderSpecific.len=0;
// unidirectional P2MP; we don't need to setup the Receiving flowspec
//qos_.SendingFlowspec.TokenRate = 0xffffffff;
//qos_.SendingFlowspec.TokenBucketSize = 0xffffffff;
//qos_.SendingFlowspec.PeakBandwidth = 0xffffffff;
//qos_.SendingFlowspec.Latency = 0xffffffff;
//qos_.SendingFlowspec.DelayVariation = 0xffffffff;
//qos_.SendingFlowspec.ServiceType = SERVICETYPE_BESTEFFORT;
// This will most probably be ignored by the service provider.
//qos_.SendingFlowspec.MaxSduSize = 0xffffffff;
//qos_.SendingFlowspec.MinimumPolicedSize = 0xffffffff;
//qos_.ReceivingFlowspec.TokenRate = 0xffffffff;
//qos_.ReceivingFlowspec.TokenBucketSize = 0xffffffff;
//qos_.ReceivingFlowspec.PeakBandwidth = 0xffffffff;
//qos_.ReceivingFlowspec.Latency = 0xffffffff;
//qos_.ReceivingFlowspec.DelayVariation = 0xffffffff;
//qos_.ReceivingFlowspec.ServiceType = SERVICETYPE_BESTEFFORT;
// This will most probably be ignored by the service provider.
//qos_.ReceivingFlowspec.MaxSduSize = 0xffffffff;
//qos_.ReceivingFlowspec.MinimumPolicedSize = 0;
/*
ACE_Flow_Spec send_fspec( 0xffffffff,
0xffffffff,
0xffffffff,
0xffffffff,
0xffffffff,
SERVICETYPE_BESTEFFORT,
// This will most probably ignored by SP.
0xffffffff,
0xffffffff,
15,
ACE_DEFAULT_THREAD_PRIORITY ),
recv_fspec( 0xffffffff,
0xffffffff,
0xffffffff,
0xffffffff,
0xffffffff,
SERVICETYPE_BESTEFFORT,
// This will most probably ignored by SP.
0xffffffff,
0,
15,
ACE_DEFAULT_THREAD_PRIORITY );
qos_.sending_flowspec( send_fspec );
qos_.receiving_flowspec( recv_fspec );
*/
#elif defined (ACE_HAS_FORE_ATM_XTI)
ACE_UNUSED_ARG (rate);
ACE_UNUSED_ARG (pktSize);
#elif defined (ACE_HAS_LINUX_ATM)
ACE_UNUSED_ARG (pktSize);
qos_.rxtp.traffic_class = ATM_CBR;
qos_.rxtp.pcr = rate;
qos_.txtp.traffic_class = ATM_CBR;
qos_.txtp.pcr = rate;
#else
ACE_UNUSED_ARG (rate);
#endif /* ACE_HAS_FORE_ATM_WS2 || ACE_HAS_FORE_ATM_XTI || ACE_HAS_LINUX_ATM */
}
void
ACE_ATM_QoS::set_rate (ACE_HANDLE fd,
int rate,
int flags)
{
ACE_TRACE ("ACE_ATM_QoS::set_rate");
#if defined (ACE_HAS_FORE_ATM_WS2) || defined (ACE_HAS_LINUX_ATM)
set_cbr_rate( rate );
ACE_UNUSED_ARG( fd );
ACE_UNUSED_ARG( flags );
#elif defined (ACE_HAS_FORE_ATM_XTI)
long optlen = 0;
qos_.buf = construct_options(fd,
rate,
flags,
&optlen);
qos_.len = optlen;
#else
ACE_UNUSED_ARG (rate);
#endif /* ACE_HAS_FORE_ATM_WS2 || ACE_HAS_LINUX_ATM || ACE_HAS_FORE_ATM_XTI */
}
char*
ACE_ATM_QoS::construct_options (ACE_HANDLE fd,
int rate,
int flags,
long *len)
{
#if defined (ACE_HAS_FORE_ATM_WS2) || defined (ACE_HAS_LINUX_ATM)
ACE_UNUSED_ARG (fd);
ACE_UNUSED_ARG (rate);
ACE_UNUSED_ARG (flags);
ACE_UNUSED_ARG (len);
return 0;
#elif defined (ACE_HAS_FORE_ATM_XTI)
struct t_opthdr *popt;
char *buf;
int qos_cells;
struct t_info info;
if (ACE_OS::t_getinfo (fd, &info) == -1)
{
ACE_OS::t_error ("t_getinfo");
return 0;
}
buf = (char *) ACE_OS::malloc (info.options);
if (buf == 0)
ACELIB_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("Unable to allocate %d bytes for options\n"),
info.options),
0);
popt = (struct t_opthdr *) buf;
if (flags & OPT_FLAGS_CPID)
{
// This constructs the T_ATM_ORIG_ADDR option, which is used to
// signal the UNI 3.1 Calling Party ID Information Element.
t_atm_addr *source_addr;
popt->len = sizeof (struct t_opthdr) + sizeof (t_atm_addr);
popt->level = T_ATM_SIGNALING;
popt->name = T_ATM_ORIG_ADDR;
popt->status = 0;
source_addr =
(t_atm_addr *)((char *) popt + sizeof (struct t_opthdr));
source_addr->address_format = T_ATM_ENDSYS_ADDR;
source_addr->address_length = ATMNSAP_ADDR_LEN;
ATMSAPAddress local_addr;
struct t_bind boundaddr;
boundaddr.addr.maxlen = sizeof(local_addr);
boundaddr.addr.buf = (char *) &local_addr;
//if (ACE_OS::t_getprotaddr(fd, &boundaddr, 0) < 0) {
if (ACE_OS::t_getname(fd,
&boundaddr.addr,
LOCALNAME) < 0)
{
ACE_OS::t_error("t_getname (local_address)");
ACELIB_ERROR ((LM_ERROR,
ACE_TEXT ("Can't get local address!\n")));
ACE_OS::free (buf);
return 0;
}
ACE_OS::memcpy(source_addr->address,
local_addr.sap.t_atm_sap_addr.address,
ATMNSAP_ADDR_LEN);
popt = T_OPT_NEXTHDR (buf, info.options , popt);
}
// This constructs all options necessary (bearer cap., QoS, and
// Traffic Descriptor) to signal for a CBR connection with the
// specified QoS in kbit/sec., and/or specify a PMP connection.
// For FORE 200e cards, the adapter shapes traffic to CBR with rate
// equal to PCR CLP=0+1 (traffic.forward.PCR_all_traffic)
qos_cells = (rate * 1000) / (48*8);
if ((qos_cells > 0 && qos_cells < LINE_RATE)
|| (ACE_BIT_ENABLED (flags, OPT_FLAGS_PMP)))
{
struct t_atm_bearer *bearer;
struct t_atm_traffic *traffic;
// T_ATM_BEARER_CAP: Broadband bearer capability
popt->len = sizeof (struct t_opthdr) + sizeof (struct t_atm_bearer);
popt->level = T_ATM_SIGNALING;
popt->name = T_ATM_BEARER_CAP;
popt->status = 0;
bearer = (struct t_atm_bearer *)((char *) popt +
sizeof (struct t_opthdr));
bearer->bearer_class = T_ATM_CLASS_X;
if (qos_cells)
{
bearer->traffic_type = T_ATM_CBR;
bearer->timing_requirements = T_ATM_END_TO_END;
}
else
{
bearer->traffic_type = 0; // UBR
bearer->timing_requirements = 0;
}
bearer->clipping_susceptibility = T_ATM_NULL;
if (ACE_BIT_ENABLED (flags, OPT_FLAGS_PMP))
bearer->connection_configuration = T_ATM_1_TO_MANY;
else
bearer->connection_configuration = T_ATM_1_TO_1;
popt = T_OPT_NEXTHDR (buf, info.options, popt);
// T_ATM_TRAFFIC: traffic descriptor
popt->len = sizeof (struct t_opthdr) + sizeof (struct t_atm_traffic);
popt->level = T_ATM_SIGNALING;
popt->name = T_ATM_TRAFFIC;
popt->status = 0;
traffic = (struct t_atm_traffic *)((char *) popt +
sizeof (struct t_opthdr));
traffic->forward.PCR_high_priority = T_ATM_ABSENT;
traffic->forward.PCR_all_traffic = qos_cells ? qos_cells : LINE_RATE;
traffic->forward.SCR_high_priority = T_ATM_ABSENT;
traffic->forward.SCR_all_traffic = T_ATM_ABSENT;
traffic->forward.MBS_high_priority = T_ATM_ABSENT;
traffic->forward.MBS_all_traffic = T_ATM_ABSENT;
traffic->forward.tagging = T_NO;
traffic->backward.PCR_high_priority = T_ATM_ABSENT;
traffic->backward.PCR_all_traffic =
(ACE_BIT_ENABLED (flags, OPT_FLAGS_PMP))
? 0 : qos_cells ? qos_cells : LINE_RATE;
traffic->backward.SCR_high_priority = T_ATM_ABSENT;
traffic->backward.SCR_all_traffic = T_ATM_ABSENT;
traffic->backward.MBS_high_priority = T_ATM_ABSENT;
traffic->backward.MBS_all_traffic = T_ATM_ABSENT;
traffic->backward.tagging = T_NO;
traffic->best_effort = qos_cells ? T_NO : T_YES;
popt = T_OPT_NEXTHDR (buf,
info.options,
popt);
}
if (qos_cells > 0 && qos_cells < LINE_RATE)
{
struct t_atm_qos *qos;
// T_ATM_QOS: Quality of Service
popt->len = sizeof (struct t_opthdr) + sizeof (struct t_atm_qos);
popt->level = T_ATM_SIGNALING;
popt->name = T_ATM_QOS;
popt->status = 0;
qos = (struct t_atm_qos *)((char *) popt + sizeof (struct t_opthdr));
qos->coding_standard = T_ATM_ITU_CODING;
qos->forward.qos_class = T_ATM_QOS_CLASS_1;
qos->backward.qos_class = T_ATM_QOS_CLASS_1;
popt = T_OPT_NEXTHDR (buf, info.options, popt);
}
// Return actual size of options and option buffer to user.
*len = (char *) popt - buf;
return buf;
#else
ACE_UNUSED_ARG (fd);
ACE_UNUSED_ARG (rate);
ACE_UNUSED_ARG (flag);
ACE_UNUSED_ARG (len);
return 0;
#endif /* ACE_HAS_FORE_ATM_WS2 */
}
ACE_END_VERSIONED_NAMESPACE_DECL
#endif /* ACE_HAS_ATM */

View File

@@ -0,0 +1,113 @@
// -*- C++ -*-
//==========================================================================
/**
* @file ATM_QoS.h
*
* @author Joe Hoffert
*/
//==========================================================================
#ifndef ACE_ATM_QoS_H
#define ACE_ATM_QoS_H
#include /**/ "ace/pre.h"
#include /**/ "ace/config-all.h"
#if !defined(ACE_LACKS_PRAGMA_ONCE)
#pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#if defined (ACE_HAS_ATM)
#if defined (ACE_HAS_FORE_ATM_WS2)
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
// just map to WS2 GQOS struct
typedef ACE_QoS ATM_QoS;
ACE_END_VERSIONED_NAMESPACE_DECL
#elif defined (ACE_HAS_FORE_ATM_XTI)
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
typedef struct netbuf ATM_QoS;
ACE_END_VERSIONED_NAMESPACE_DECL
#elif defined (ACE_HAS_LINUX_ATM)
#include /**/ "atm.h"
#include "ace/ATM_Params.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
typedef struct atm_qos ATM_QoS;
ACE_END_VERSIONED_NAMESPACE_DECL
#else
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
typedef int ATM_QoS;
ACE_END_VERSIONED_NAMESPACE_DECL
#endif /* ACE_HAS_FORE_ATM_WS2 || ACE_HAS_FORE_ATM_XTI || ACE_HAS_LINUX_ATM */
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
/**
* @class ACE_ATM_QoS
*
* @brief Define the QoS parameters for ATM
*
* This class wraps up QoS parameters for both ATM/XTI and
* ATM/WinSock2 to make the mechanism for the ATM protocol
* transparent.
*/
class ACE_Export ACE_ATM_QoS
{
public:
// Constants used for ATM options
static const long LINE_RATE;
static const int OPT_FLAGS_CPID;
static const int OPT_FLAGS_PMP;
static const int DEFAULT_SELECTOR;
static const int DEFAULT_PKT_SIZE;
// = Initializattion and termination methods.
/// Default constructor.
ACE_ATM_QoS(int = DEFAULT_PKT_SIZE);
/// Constructor with a CBR rate.
ACE_ATM_QoS(int,
int = DEFAULT_PKT_SIZE);
~ACE_ATM_QoS ();
/// Set the rate.
void set_rate (ACE_HANDLE,
int,
int);
/// Set CBR rate in cells per second.
void set_cbr_rate (int,
int = DEFAULT_PKT_SIZE);
/// Get ATM_QoS struct.
ATM_QoS get_qos (void);
/// Dump the state of an object.
void dump (void) const;
/// Declare the dynamic allocation hooks.
ACE_ALLOC_HOOK_DECLARE;
protected:
/// Construct QoS options.
char* construct_options(ACE_HANDLE,
int,
int,
long*);
private:
ATM_QoS qos_;
};
ACE_END_VERSIONED_NAMESPACE_DECL
#if defined (__ACE_INLINE__)
#include "ace/ATM_QoS.inl"
#endif /* __ACE_INLINE__ */
#endif /* ACE_HAS_ATM */
#include /**/ "ace/post.h"
#endif /* ACE_ATM_QoS_H */

View File

@@ -0,0 +1,26 @@
// -*- C++ -*-
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
ACE_INLINE void
ACE_ATM_QoS::dump (void) const
{
#if defined (ACE_HAS_DUMP)
ACE_TRACE ("ACE_ATM_QoS::dump");
#endif /* ACE_HAS_DUMP */
}
ACE_INLINE
ACE_ATM_QoS::~ACE_ATM_QoS ()
{
ACE_TRACE ("ACE_ATM_QoS::~ACE_ATM_QoS");
}
ACE_INLINE
ATM_QoS
ACE_ATM_QoS::get_qos (void)
{
ACE_TRACE ("ACE_ATM_QoS::get_qos");
return qos_;
}
ACE_END_VERSIONED_NAMESPACE_DECL

View File

@@ -0,0 +1,288 @@
#include "ace/ATM_Stream.h"
#if defined (ACE_HAS_ATM)
#include "ace/OS_NS_string.h"
#if !defined (__ACE_INLINE__)
#include "ace/ATM_Stream.inl"
#endif /* __ACE_INLINE__ */
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
ACE_ALLOC_HOOK_DEFINE (ACE_ATM_Stream)
char*
ACE_ATM_Stream::get_peer_name (void) const
{
ACE_TRACE ("ACE_ATM_Stream::get_peer_name");
#if defined (ACE_HAS_FORE_ATM_XTI)
// // Use t_getprotaddr for XTI/ATM
// struct t_bind *localaddr
// = (struct t_bind *) ACE_OS::t_alloc (get_handle (),
// T_BIND,
// T_ADDR);
// struct t_bind *peeraddr
// = (struct t_bind *) ACE_OS::t_alloc (get_handle (),
// T_BIND,
// T_ADDR);
// ::t_getprotaddr (get_handle (),
// localaddr,
// peeraddr);
// char* connected_name = (char*) ACE_OS::malloc (peeraddr->addr.len + 1);
// ACE_OS::strcpy (connected_name,
// peeraddr->addr.buf);
// ACE_OS::t_free ((char *) localaddr,
// T_BIND);
// ACE_OS::t_free ((char *) peeraddr,
// T_BIND);
// return (connected_name);
#error "This doesn't seem to work. May need to jimmy-rig something with the"
#error "/etc/xti_hosts file - Ugh!"
ACE_ATM_Addr sa;
struct netbuf name;
name.maxlen = sa.get_size ();
name.buf = (char *) sa.get_addr ();
ACE_OS::t_getname (this->get_handle (), &name, REMOTENAME);
// ACE_OS::ioctl (this->get_handle (),
// TI_GETPEERNAME,
// &name);
return (name.buf);
#elif defined (ACE_HAS_FORE_ATM_WS2)
// Use getpeername for WinSock2.
struct sockaddr_atm name;
ACE_OS::memset (&name, 0, sizeof (name));
int nameSize = sizeof (name);
if (ACE_OS::getpeername (this->get_handle (),
(struct sockaddr *) &name,
&nameSize) != 0) {
return 0;
}
char buffer[256];
for (unsigned int index = 0; index < ATM_ADDR_SIZE - 1; index++) {
buffer[ index * 3 ] = '\0';
ACE_OS::sprintf (buffer, "%s%02x.", buffer, name.satm_number.Addr[ index ]);
}
buffer[ (ATM_ADDR_SIZE - 1) * 3 ] = '\0';
ACE_OS::sprintf (buffer, "%s%02x.", buffer, 0);
buffer[ ATM_ADDR_SIZE * 3 - 1 ] = '\0';
for (index = 0; index < ACE_OS::strlen (buffer); ++index)
buffer[index] = ACE_OS::ace_tolower (buffer[index]);
ifstream atm_hosts ("C:/WINNT/atmhosts");
assert (atm_hosts.is_open ());
// Find the host address in the ATM hosts file and return the
// host name
char line[256];
char *host_ptr, *host_name = 0;
ACE_NEW_RETURN (host_name, char[256], 0);
while (!atm_hosts.eof ()) {
atm_hosts.getline (line, 256);
// Convert the line to lower case to ease comparison
for (index = 0; index < ACE_OS::strlen (line); ++index)
line[index] = ACE_OS::ace_tolower (line[index]);
if (ACE_OS::strstr (line, buffer) != 0)
{
char *strtok_p;
// Grab the second token which is the host name
ACE_OS::strtok_r (line, " \t", &strtok_p);
host_ptr = ACE_OS::strtok (0, " \t", &strtok_p);
ACE_OS::strcpy (host_name, host_ptr);
break;
}
}
return host_name;
#elif defined (ACE_HAS_LINUX_ATM)
ATM_Addr name;
int nameSize = sizeof (name.sockaddratmsvc);
if (ACE_OS::getpeername (this->get_handle (),
(struct sockaddr *) & (name.sockaddratmsvc),
&nameSize) < 0) {
ACE_OS::perror ("ACE_ATM_Stream (get_peer_name) : ");
return 0;
}
static ACE_TCHAR buffer[MAX_ATM_ADDR_LEN + 1];
int total_len;
if ((total_len = atm2text (buffer,sizeof buffer,
(struct sockaddr *) & (name.sockaddratmsvc),
A2T_PRETTY|A2T_NAME)) < 0) {
ACELIB_DEBUG ((LM_DEBUG,ACE_TEXT ("ACE_ATM_Stream (get_peer_name) :%d"),errno));
return 0;
}
return (char*) buffer;
#else
return 0;
#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 || ACE_HAS_LINUX_ATM */
}
ACE_HANDLE
ACE_ATM_Stream::get_handle (void) const
{
ACE_TRACE ("ACE_ATM_Stream::get_handle");
#if defined (ACE_HAS_FORE_ATM_XTI) || defined (ACE_HAS_FORE_ATM_WS2) || defined (ACE_HAS_LINUX_ATM)
return stream_.get_handle ();
#else
return 0;
#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 || ACE_HAS_LINUX_ATM */
}
int
ACE_ATM_Stream::get_vpi_vci (ACE_UINT16 &vpi,
ACE_UINT16 &vci) const
{
ACE_TRACE ("ACE_ATM_Stream::get_vpi_vci");
#if defined (ACE_HAS_FORE_ATM_XTI)
struct t_atm_conn_prop conn_prop;
char* connect_opts = (char *) &conn_prop;
int opt_size = sizeof (t_atm_conn_prop);
struct t_info info;
struct t_optmgmt opt_req, opt_ret;
if (ACE_OS::t_getinfo (stream_.get_handle (),
&info) < 0)
{
ACE_OS::t_error ("t_getinfo");
return -1;
}
char *buf_req = (char *) ACE_OS::malloc (info.options);
if (buf_req == 0)
{
ACE_OS::fprintf (stderr,
"Unable to allocate %ld bytes for options\n",
info.options);
return -1;
}
char *buf_ret = (char *) ACE_OS::malloc (info.options);
if (buf_ret == 0)
{
ACE_OS::fprintf (stderr,
"Unable to allocate %ld bytes for options\n",
info.options);
return -1;
}
ACE_OS::memset (&opt_req, 0, sizeof (opt_req));
ACE_OS::memset (&opt_ret, 0, sizeof (opt_ret));
struct t_opthdr *popt = (struct t_opthdr *) buf_req;
struct t_opthdr *popt_ret = (struct t_opthdr *) buf_ret;
popt->len= sizeof (struct t_opthdr) + opt_size;
// We are only concerned with SVCs so no other check or values are needed
// here.
popt->level = T_ATM_SIGNALING;
popt->name = T_ATM_CONN_PROP;
popt->status = 0;
opt_req.opt.len = popt->len;
opt_req.opt.buf = (char *) popt;
opt_req.flags = T_CURRENT;
popt = T_OPT_NEXTHDR (buf_req,
info.options,
popt);
opt_ret.opt.maxlen = info.options;
opt_ret.opt.buf = (char *) popt_ret;
if (ACE_OS::t_optmgmt (stream_.get_handle (),
&opt_req,
&opt_ret) < 0) {
ACE_OS::t_error ("t_optmgmt");
return -1;
}
ACE_OS::memcpy (connect_opts,
(char *) popt_ret + sizeof (struct t_opthdr),
opt_size);
ACE_OS::free (buf_ret);
ACE_OS::free (buf_req);
vpi = conn_prop.vpi;
vci = conn_prop.vci;
return 0;
#elif defined (ACE_HAS_FORE_ATM_WS2)
ATM_CONNECTION_ID connID;
DWORD bytes = 0;
if (::WSAIoctl ((int) this -> get_handle (),
SIO_GET_ATM_CONNECTION_ID,
0,
0,
(LPVOID) &connID,
sizeof (ATM_CONNECTION_ID),
&bytes,
0,
0)
== SOCKET_ERROR) {
ACE_OS::printf ("Error: WSAIoctl %d\n", WSAGetLastError ());
}
vpi = (ACE_UINT16) connID.VPI;
vci = (ACE_UINT16) connID.VCI;
return 0;
#elif defined (ACE_HAS_LINUX_ATM)
#if defined (SO_ATMPVC) /* atm version>=0.62 */
struct sockaddr_atmpvc mypvcaddr;
int addrpvclen = sizeof (mypvcaddr);
if (ACE_OS::getsockopt (stream_.get_handle (),
SOL_ATM,
SO_ATMPVC,
reinterpret_cast<char*> (&mypvcaddr),
&addrpvclen) < 0) {
ACELIB_DEBUG (LM_DEBUG,
ACE_TEXT ("ACE_ATM_Stream::get_vpi_vci: getsockopt %d\n"),
errno);
return -1;
}
vpi = (ACE_UINT16) mypvcaddr.sap_addr.vpi;
vci = (ACE_UINT16) mypvcaddr.sap_addr.vci;
return 0;
#elif defined (SO_VCID) /* patch for atm version 0.59 */
struct atm_vcid mypvcid;
int pvcidlen = sizeof (mypvcid);
if (ACE_OS::getsockopt (stream_.get_handle (),
SOL_ATM,SO_VCID,
reinterpret_cast<char*> (&mypvcid),
&pvcidlen) < 0) {
ACELIB_DEBUG (LM_DEBUG,
ACE_TEXT ("ACE_ATM_Stream::get_vpi_vci: getsockopt %d\n"),
errno);
return -1;
}
vpi = (ACE_UINT16) mypvcid.vpi;
vci = (ACE_UINT16) mypvcid.vci;
return 0;
#else
ACELIB_DEBUG (LM_DEBUG,
ACE_TEXT ("ACE_ATM_Stream::get_vpi_vci: Not implemented in this ATM version. Update to >= 0.62\n Or patch 0.59"));
ACE_UNUSED_ARG (vci);
ACE_UNUSED_ARG (vpi);
return -1;
#endif /* SO_ATMPVC || SO_VCID */
#else
return -1;
#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 || ACE_HAS_LINUX_ATM */
}
ACE_END_VERSIONED_NAMESPACE_DECL
#endif /* ACE_HAS_ATM */

View File

@@ -0,0 +1,105 @@
/* -*- C++ -*- */
//=============================================================================
/**
* @file ATM_Stream.h
*
* @author Joe Hoffert
*/
//=============================================================================
#ifndef ACE_ATM_STREAM_H
#define ACE_ATM_STREAM_H
#include /**/ "ace/pre.h"
#include /**/ "ace/config-all.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#if defined (ACE_HAS_ATM)
#include "ace/ATM_Addr.h"
#include "ace/ATM_Params.h"
#if defined (ACE_WIN32)
#include "ace/SOCK_Stream.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
typedef ACE_SOCK_Stream ATM_Stream;
ACE_END_VERSIONED_NAMESPACE_DECL
#else
#include "ace/TLI_Stream.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
typedef ACE_TLI_Stream ATM_Stream;
ACE_END_VERSIONED_NAMESPACE_DECL
#endif
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
/**
* @class ACE_ATM_Stream
*
* @brief Defines the member functions for ACE_ATM_Stream abstraction.
*/
class ACE_Export ACE_ATM_Stream
{
public:
// = Initialization and termination methods.
/// Default constructor.
ACE_ATM_Stream (void);
// = ATM-specific open and shutdown operations.
/// open the stream.
int open (ACE_ATM_Params params = ACE_ATM_Params());
/// Close down and release resources.
int close (void);
/// Get the underlying handle.
ACE_HANDLE get_handle (void) const;
/// Get the underlying stream.
ATM_Stream& get_stream (void);
/// Get the name of the connected host.
char* get_peer_name (void) const;
/// Get the VPI and VCI of the stream.
int get_vpi_vci (ACE_UINT16 &vpi,
ACE_UINT16 &vci) const;
/// Recv an n byte buffer from the connected transport mechanism.
ssize_t recv (void *buf,
size_t n,
int *flags = 0) const;
/// Send exactly n bytes to the connected transport mechanism.
ssize_t send_n (const void *buf,
size_t n,
int flags) const;
// = Meta-type info
typedef ACE_ATM_Addr PEER_ADDR;
/// Dump the state of an object.
void dump (void) const;
/// Declare the dynamic allocation hooks.
ACE_ALLOC_HOOK_DECLARE;
private:
/// Typedef'd to the appropriate stream mechanism above.
ATM_Stream stream_;
};
ACE_END_VERSIONED_NAMESPACE_DECL
#if defined (__ACE_INLINE__)
#include "ace/ATM_Stream.inl"
#endif /* __ACE_INLINE__ */
#endif /* ACE_HAS_ATM */
#include /**/ "ace/post.h"
#endif /* ACE_ATM_STREAM_H */

View File

@@ -0,0 +1,130 @@
// -*- C++ -*-
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
ACE_INLINE void
ACE_ATM_Stream::dump (void) const
{
#if defined (ACE_HAS_DUMP)
ACE_TRACE ("ACE_ATM_Stream::dump");
#endif /* ACE_HAS_DUMP */
}
ACE_INLINE
ACE_ATM_Stream::ACE_ATM_Stream (void)
{
ACE_TRACE ("ACE_ATM_Stream::ACE_ATM_Stream");
}
ACE_INLINE
int
ACE_ATM_Stream::open (ACE_ATM_Params params)
{
ACE_TRACE ("ACE_ATM_Stream::open");
#if defined (ACE_HAS_FORE_ATM_XTI)
ACE_HANDLE handle = stream_.open (params.get_device(),
params.get_oflag(),
params.get_info());
return (handle == ACE_INVALID_HANDLE ? -1 : 0);
#elif defined (ACE_HAS_FORE_ATM_WS2)
params.set_flags( ACE_FLAG_MULTIPOINT_C_ROOT | ACE_FLAG_MULTIPOINT_D_ROOT );
int retval = stream_.open (params.get_type(),
params.get_protocol_family(),
params.get_protocol(),
params.get_protocol_info(),
params.get_sock_group(),
params.get_flags(),
params.get_reuse_addr());
if (retval == -1)
return -1;
struct sockaddr_atm sock_addr;
ACE_OS::memset(&sock_addr, 0, sizeof(struct sockaddr_atm));
sock_addr.satm_family = AF_ATM;
sock_addr.satm_number.AddressType=ADDR_ANY;
sock_addr.satm_number.NumofDigits = ATM_ADDR_SIZE;
sock_addr.satm_blli.Layer2Protocol = SAP_FIELD_ABSENT;
sock_addr.satm_blli.Layer3Protocol = SAP_FIELD_ABSENT;
sock_addr.satm_bhli.HighLayerInfoType = SAP_FIELD_ABSENT;
if (ACE_OS::bind(get_handle(),
(struct sockaddr FAR *)&sock_addr,
sizeof(struct sockaddr_atm)) < 0)
{
ACE_OS::printf("Error binding local address: %d",WSAGetLastError());
return -1;
}
return 0;
#else
ACE_UNUSED_ARG(params);
return 0;
#endif /* ACE_HAS_FORE_ATM_XTI */
}
ACE_INLINE
int
ACE_ATM_Stream::close (void)
{
ACE_TRACE ("ACE_ATM_Stream::close");
#if defined (ACE_HAS_FORE_ATM_XTI) || defined (ACE_HAS_FORE_ATM_WS2)
return stream_.close ();
#else
return 0;
#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 */
}
ACE_INLINE
ATM_Stream&
ACE_ATM_Stream::get_stream (void)
{
ACE_TRACE ("ACE_ATM_Stream::get_stream");
return stream_;
}
ACE_INLINE
ssize_t
ACE_ATM_Stream::recv (void *buf,
size_t n,
int *flags) const
{
ACE_TRACE ("ACE_ATM_Stream::recv");
#if defined (ACE_HAS_FORE_ATM_XTI)
return stream_.recv (buf,
n,
flags);
#elif defined (ACE_HAS_FORE_ATM_WS2)
return stream_.recv (buf,
n);
#else
ACE_UNUSED_ARG(buf);
ACE_UNUSED_ARG(n);
ACE_UNUSED_ARG(flags);
return 0;
#endif /* ACE_HAS_FORE_ATM_XTI */
}
ACE_INLINE
ssize_t
ACE_ATM_Stream::send_n (const void *buf,
size_t n,
int flags) const
{
ACE_TRACE ("ACE_ATM_Stream::send_n");
#if defined (ACE_HAS_FORE_ATM_XTI)
return stream_.send_n (buf,
n,
flags);
#elif defined (ACE_HAS_FORE_ATM_WS2)
return stream_.send_n (buf,
n,
flags);
#else
ACE_UNUSED_ARG(buf);
ACE_UNUSED_ARG(n);
ACE_UNUSED_ARG(flags);
return 0;
#endif /* ACE_HAS_FORE_ATM_XTI */
}
ACE_END_VERSIONED_NAMESPACE_DECL

View File

@@ -0,0 +1,26 @@
//$Id: Abstract_Timer_Queue.cpp 95334 2011-12-15 12:52:50Z msmit $
#ifndef ACE_ABSTRACT_TIMER_QUEUE_CPP
#define ACE_ABSTRACT_TIMER_QUEUE_CPP
#include "ace/config-all.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "ace/Abstract_Timer_Queue.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
// Even though the destructor is pure virtual you must provide an
// implementation. Most people know this, but sometimes we all
// forget, and we might be tempted to remove this code.
template<typename TYPE>
ACE_Abstract_Timer_Queue<TYPE>::
~ACE_Abstract_Timer_Queue ()
{
}
ACE_END_VERSIONED_NAMESPACE_DECL
#endif /* ACE_ABSTRACT_TIMER_QUEUE_CPP */

View File

@@ -0,0 +1,230 @@
//$Id: Abstract_Timer_Queue.h 95368 2011-12-19 13:38:49Z mcorino $
#ifndef ACE_ABSTRACT_TIMER_QUEUE_H
#define ACE_ABSTRACT_TIMER_QUEUE_H
#include /**/ "ace/pre.h"
/**
* @file Abstract_Timer_Queue.h
*
* @author Carlos O'Ryan <coryan@atdesk.com>
*
* Based on classes and files developed by Doug Schmidt, Darrell
* Brunsch, Irfan Pyarali and a cast of thousands.
*/
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
// Forward declares
class ACE_Time_Value;
class ACE_Command_Base;
template<typename TYPE> class ACE_Timer_Queue_Iterator_T;
template<typename TYPE> class ACE_Timer_Node_T;
/**
* @class ACE_Abstract_Timer_Queue
*
* @brief Base class for all timer queues of a single type.
*
* This is a base class for all the timer queues, regardless of
* locking strategy, upcall mechanism, internal implementation, etc.
* The class was motivated by bug 3706:
* http://bugzilla.dre.vanderbilt.edu/show_bug.cgi?id=3706
* In short, the Reactor (and potentially other classes) want to refer
* to timer queues regardless of the implementation internals.
*/
template<typename TYPE>
class ACE_Abstract_Timer_Queue
{
public:
/// Destructor
virtual ~ACE_Abstract_Timer_Queue (void) = 0;
/// True if queue is empty, else false.
virtual bool is_empty (void) const = 0;
/// Returns the time of the earlier node in the Timer_Queue. Must
/// be called on a non-empty queue.
virtual const ACE_Time_Value &earliest_time (void) const = 0;
/**
* Schedule @a type that will expire at @a future_time, which is
* specified in absolute time. If it expires then @a act is passed
* in as the value to the <functor>. If @a interval is != to
* ACE_Time_Value::zero then it is used to reschedule the @a type
* automatically, using relative time to the current <gettimeofday>.
* This method returns a <timer_id> that uniquely identifies the the
* @a type entry in an internal list. This <timer_id> can be used to
* cancel the timer before it expires. The cancellation ensures
* that <timer_ids> are unique up to values of greater than 2
* billion timers. As long as timers don't stay around longer than
* this there should be no problems with accidentally deleting the
* wrong timer. Returns -1 on failure (which is guaranteed never to
* be a valid <timer_id>).
*/
virtual long schedule (const TYPE &type,
const void *act,
const ACE_Time_Value &future_time,
const ACE_Time_Value &interval = ACE_Time_Value::zero) = 0;
/**
* Run the <functor> for all timers whose values are <= @a current_time.
* This does not account for <timer_skew>. Returns the number of
* timers canceled.
*/
virtual int expire (const ACE_Time_Value &current_time) = 0;
/**
* Run the <functor> for all timers whose values are <=
* <ACE_OS::gettimeofday>. Also accounts for <timer_skew>.
*
* Depending on the resolution of the underlying OS the system calls
* like select()/poll() might return at time different than that is
* specified in the timeout. Suppose the OS guarantees a resolution of t ms.
* The timeline will look like
*
* A B
* | |
* V V
* |-------------|-------------|-------------|-------------|
* t t t t t
*
*
* If you specify a timeout value of A, then the timeout will not occur
* at A but at the next interval of the timer, which is later than
* that is expected. Similarly, if your timeout value is equal to B,
* then the timeout will occur at interval after B. Now depending upon the
* resolution of your timeouts and the accuracy of the timeouts
* needed for your application, you should set the value of
* <timer_skew>. In the above case, if you want the timeout A to fire
* no later than A, then you should specify your <timer_skew> to be
* A % t.
*
* The timeout value should be specified via the macro ACE_TIMER_SKEW
* in your config.h file. The default value is zero.
*
* Things get interesting if the t before the timeout value B is zero
* i.e your timeout is less than the interval. In that case, you are
* almost sure of not getting the desired timeout behaviour. Maybe you
* should look for a better OS :-)
*
* Returns the number of timers canceled.
*/
virtual int expire (void) = 0;
/**
* A couple of classes using Timer_Queues need to dispatch a single
* event at a time. But before they dispatch the event they need to
* release a lock, signal other threads, etc.
*
* This member function should be used in that case. The additional
* operations to be called just before dispatching the event, and
* only if an event will be dispatched, are encapsulated in the
* ACE_Command_Base object.
*/
virtual int expire_single(ACE_Command_Base & pre_dispatch_command) = 0;
/**
* Resets the interval of the timer represented by @a timer_id to
* @a interval, which is specified in relative time to the current
* <gettimeofday>. If @a interval is equal to
* ACE_Time_Value::zero, the timer will become a non-rescheduling
* timer. Returns 0 if successful, -1 if not.
*/
virtual int reset_interval (long timer_id,
const ACE_Time_Value &interval) = 0;
/**
* Cancel all timer associated with @a type. If
* @a dont_call_handle_close is 0 then the <functor> will be invoked,
* which typically invokes the <handle_close> hook. Returns number
* of timers cancelled.
*/
virtual int cancel (const TYPE &type,
int dont_call_handle_close = 1) = 0;
/**
* Cancel the single timer that matches the @a timer_id value (which
* was returned from the <schedule> method). If act is non-NULL
* then it will be set to point to the ``magic cookie'' argument
* passed in when the timer was registered. This makes it possible
* to free up the memory and avoid memory leaks. If
* @a dont_call_handle_close is 0 then the <functor> will be invoked,
* which typically calls the <handle_close> hook. Returns 1 if
* cancellation succeeded and 0 if the @a timer_id wasn't found.
*/
virtual int cancel (long timer_id,
const void **act = 0,
int dont_call_handle_close = 1) = 0;
/**
* Close timer queue. Cancels all timers.
*/
virtual int close (void) = 0;
/**
* Returns the current time of day. This method allows different
* implementations of the timer queue to use special high resolution
* timers.
*/
virtual ACE_Time_Value gettimeofday (void) = 0;
/**
* Allows applications to control how the timer queue gets the time
* of day.
* @deprecated Use TIME_POLICY support instead. See Timer_Queue_T.h
*/
virtual void gettimeofday (ACE_Time_Value (*gettimeofday)(void)) = 0;
/// Determine the next event to timeout. Returns @a max if there are
/// no pending timers or if all pending timers are longer than max.
/// This method acquires a lock internally since it modifies internal state.
virtual ACE_Time_Value *calculate_timeout (ACE_Time_Value *max) = 0;
/**
* Determine the next event to timeout. Returns @a max if there are
* no pending timers or if all pending timers are longer than max.
* <the_timeout> should be a pointer to storage for the timeout value,
* and this value is also returned. This method does not acquire a
* lock internally since it doesn't modify internal state. If you
* need to call this method when the queue is being modified
* concurrently, however, you should make sure to acquire the <mutex()>
* externally before making the call.
*/
virtual ACE_Time_Value *calculate_timeout (ACE_Time_Value *max,
ACE_Time_Value *the_timeout) = 0;
/**
* Return the current time, using the right time policy and any
* timer skew defined in derived classes.
*/
virtual ACE_Time_Value current_time() = 0;
/// Type of Iterator.
typedef ACE_Timer_Queue_Iterator_T<TYPE> ITERATOR;
/// Returns a pointer to this ACE_Timer_Queue's iterator.
virtual ITERATOR & iter (void) = 0;
/// Removes the earliest node from the queue and returns it
virtual ACE_Timer_Node_T<TYPE> *remove_first (void) = 0;
/// Reads the earliest node from the queue and returns it.
virtual ACE_Timer_Node_T<TYPE> *get_first (void) = 0;
/// Dump the state of a object.
virtual void dump (void) const = 0;
};
ACE_END_VERSIONED_NAMESPACE_DECL
#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
#include "ace/Abstract_Timer_Queue.cpp"
#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
#pragma implementation ("Abstract_Timer_Queue.cpp")
#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
#include /**/ "ace/post.h"
#endif /* ACE_ABSTRACT_TIMER_QUEUE_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,701 @@
// -*- C++ -*-
//=============================================================================
/**
* @file Acceptor.h
*
* @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
*/
//=============================================================================
#ifndef ACE_ACCEPTOR_H
#define ACE_ACCEPTOR_H
#include /**/ "ace/pre.h"
#include "ace/Service_Object.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "ace/Strategies_T.h"
#include "ace/Synch_Options.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
/**
* @class ACE_Acceptor
*
* @brief Abstract factory for creating a service handler
* (SVC_HANDLER), accepting into the SVC_HANDLER, and
* activating the SVC_HANDLER.
*
* Implements the basic strategy for passively establishing
* connections with clients. An ACE_Acceptor inherits from
* ACE_Service_Object, which in turn inherits from ACE_Event_Handler.
* This enables the ACE_Reactor to dispatch the ACE_Acceptor's
* handle_input method when connection events occur. The handle_input
* method performs the ACE_Acceptor's default creation, connection
* establishment, and service activation strategies. These strategies
* can be overridden by subclasses individually or as a group.
*
* An ACE_Acceptor is parameterized by concrete types that conform to
* the interfaces of SVC_HANDLER and PEER_ACCEPTOR described below.
*
* @tparam SVC_HANDLER The name of the concrete type that performs the
* application-specific service. The SVC_HANDLER typically
* inherits from ACE_Svc_Handler. @see Svc_Handler.h.
*
* @tparam PEER_ACCEPTOR The name of the class that implements the
* PEER_ACCEPTOR endpoint (e.g., ACE_SOCK_Acceptor) to
* passively establish connections. A PEER_ACCEPTOR
* implementation must provide a PEER_STREAM and PEER_ADDR
* trait to identify the type of stream (e.g.,
* ACE_SOCK_Stream) and type of address (e.g., ACE_INET_Addr)
* used by the endpoint.
*/
template <typename SVC_HANDLER, typename PEER_ACCEPTOR>
class ACE_Acceptor : public ACE_Service_Object
{
public:
// Useful STL-style traits.
typedef typename PEER_ACCEPTOR::PEER_ADDR addr_type;
typedef PEER_ACCEPTOR acceptor_type;
typedef SVC_HANDLER handler_type;
typedef typename SVC_HANDLER::stream_type stream_type;
/// "Do-nothing" constructor.
ACE_Acceptor (ACE_Reactor * = 0,
int use_select = 1);
/**
* Open the contained @c PEER_ACCEPTOR object to begin listening, and
* register with the specified reactor for accept events. An
* acceptor can only listen to one port at a time, so make sure to
* @c close() the acceptor before calling @c open() again.
*
* The @c PEER_ACCEPTOR handle is put into non-blocking mode as a
* safeguard against the race condition that can otherwise occur
* between the time when the passive-mode socket handle is "ready"
* and when the actual @c accept() call is made. During this
* interval, the client can shutdown the connection, in which case,
* the @c accept() call can hang.
*
* @param local_addr The address to listen at.
* @param reactor Pointer to the ACE_Reactor instance to register
* this object with. The default is the singleton.
* @param flags Flags to control what mode an accepted socket
* will be put into after it is accepted. The only
* legal value for this argument is @c ACE_NONBLOCK,
* which enables non-blocking mode on the accepted
* peer stream object in @c SVC_HANDLER. The default
* is 0.
* @param use_select Affects behavior when called back by the reactor
* when a connection can be accepted. If non-zero,
* this object will accept all pending connections,
* instead of just the one that triggered the reactor
* callback. Uses ACE_OS::select() internally to
* detect any remaining acceptable connections.
* The default is 1.
* @param reuse_addr Passed to the @c PEER_ACCEPTOR::open() method with
* @p local_addr. Generally used to request that the
* OS allow reuse of the listen port. The default is 1.
*/
ACE_Acceptor (const typename PEER_ACCEPTOR::PEER_ADDR &local_addr,
ACE_Reactor *reactor = ACE_Reactor::instance (),
int flags = 0,
int use_select = 1,
int reuse_addr = 1);
/**
* Open the contained @c PEER_ACCEPTOR object to begin listening, and
* register with the specified reactor for accept events. An
* acceptor can only listen to one port at a time, so make sure to
* @c close() the acceptor before calling @c open() again.
*
* The @c PEER_ACCEPTOR handle is put into non-blocking mode as a
* safeguard against the race condition that can otherwise occur
* between the time when the passive-mode socket handle is "ready"
* and when the actual @c accept() call is made. During this
* interval, the client can shutdown the connection, in which case,
* the @c accept() call can hang.
*
* @param local_addr The address to listen at.
* @param reactor Pointer to the ACE_Reactor instance to register
* this object with. The default is the singleton.
* @param flags Flags to control what mode an accepted socket
* will be put into after it is accepted. The only
* legal value for this argument is @c ACE_NONBLOCK,
* which enables non-blocking mode on the accepted
* peer stream object in @c SVC_HANDLER. The default
* is 0.
* @param use_select Affects behavior when called back by the reactor
* when a connection can be accepted. If non-zero,
* this object will accept all pending connections,
* instead of just the one that triggered the reactor
* callback. Uses ACE_OS::select() internally to
* detect any remaining acceptable connections.
* The default is 1.
* @param reuse_addr Passed to the @c PEER_ACCEPTOR::open() method with
* @p local_addr. Generally used to request that the
* OS allow reuse of the listen port. The default is 1.
*
* @retval 0 Success
* @retval -1 Failure, @c errno contains an error code.
*/
virtual int open (const typename PEER_ACCEPTOR::PEER_ADDR &local_addr,
ACE_Reactor *reactor = ACE_Reactor::instance (),
int flags = 0,
int use_select = 1,
int reuse_addr = 1);
/// Close down the Acceptor's resources.
virtual ~ACE_Acceptor (void);
/// Return the underlying PEER_ACCEPTOR object.
virtual operator PEER_ACCEPTOR &() const;
/// Return the underlying PEER_ACCEPTOR object.
virtual PEER_ACCEPTOR &acceptor (void) const;
/// Returns the listening acceptor's {ACE_HANDLE}.
virtual ACE_HANDLE get_handle (void) const;
/// Close down the Acceptor
virtual int close (void);
/// In the event that an accept fails, this method will be called and
/// the return value will be returned from handle_input().
virtual int handle_accept_error (void);
/// Dump the state of an object.
void dump (void) const;
/// Declare the dynamic allocation hooks.
ACE_ALLOC_HOOK_DECLARE;
protected:
// = The following three methods define the Acceptor's strategies
// for creating, accepting, and activating SVC_HANDLER's,
// respectively.
/**
* Bridge method for creating a SVC_HANDLER. The default is to
* create a new {SVC_HANDLER} if {sh} == 0, else {sh} is unchanged.
* However, subclasses can override this policy to perform
* SVC_HANDLER creation in any way that they like (such as creating
* subclass instances of SVC_HANDLER, using a singleton, dynamically
* linking the handler, etc.). Returns -1 on failure, else 0.
*/
virtual int make_svc_handler (SVC_HANDLER *&sh);
/**
* Bridge method for accepting the new connection into the
* @a svc_handler. The default behavior delegates to the
* PEER_ACCEPTOR::accept.
*/
virtual int accept_svc_handler (SVC_HANDLER *svc_handler);
/**
* Bridge method for activating a @a svc_handler with the appropriate
* concurrency strategy. The default behavior of this method is to
* activate the SVC_HANDLER by calling its open() method (which
* allows the SVC_HANDLER to define its own concurrency strategy).
* However, subclasses can override this strategy to do more
* sophisticated concurrency activations (such as making the
* SVC_HANDLER as an "active object" via multi-threading or
* multi-processing).
*/
virtual int activate_svc_handler (SVC_HANDLER *svc_handler);
// = Demultiplexing hooks.
/// Perform termination activities when {this} is removed from the
/// {reactor}.
virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE,
ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK);
/// Accepts all pending connections from clients, and creates and
/// activates SVC_HANDLERs.
virtual int handle_input (ACE_HANDLE);
// = Dynamic linking hooks.
/// Default version does no work and returns -1. Must be overloaded
/// by application developer to do anything meaningful.
virtual int init (int argc, ACE_TCHAR *argv[]);
/// Calls {handle_close}.
virtual int fini (void);
/// Default version returns address info in {buf}.
virtual int info (ACE_TCHAR **buf, size_t) const;
public:
// = Service management hooks.
/// This method calls {Reactor::suspend}.
virtual int suspend (void);
/// This method calls {Reactor::resume}.
virtual int resume (void);
protected:
/// Concrete factory for accepting connections from clients...
PEER_ACCEPTOR peer_acceptor_;
/// Needed to reopen the socket if {accept} fails.
typename PEER_ACCEPTOR::PEER_ADDR peer_acceptor_addr_;
/**
* Flags that indicate how {SVC_HANDLER}'s should be initialized
* prior to being activated. Right now, the only flag that is
* processed is {ACE_NONBLOCK}, which enabled non-blocking I/O on
* the {SVC_HANDLER} when it is opened.
*/
int flags_;
/// Flag that indicates whether it shall use {select} in the
/// {accept}-loop.
int use_select_;
/// Needed to reopen the socket if {accept} fails.
int reuse_addr_;
};
/**
* @class ACE_Strategy_Acceptor
*
* @brief Abstract factory for creating a service handler
* (SVC_HANDLER), accepting into the SVC_HANDLER, and activating
* the SVC_HANDLER.
*
* Implements a flexible and extensible set of strategies for
* passively establishing connections with clients. There are
* three main strategies: (1) creating a SVC_HANDLER, (2)
* passively accepting a new connection from a client into the
* SVC_HANDLER, and (3) activating the SVC_HANDLER with a
* particular concurrency mechanism.
*/
template <typename SVC_HANDLER, typename PEER_ACCEPTOR>
class ACE_Strategy_Acceptor
: public ACE_Acceptor <SVC_HANDLER, PEER_ACCEPTOR>
{
public:
// Useful STL-style traits.
typedef ACE_Creation_Strategy<SVC_HANDLER>
creation_strategy_type;
typedef ACE_Accept_Strategy<SVC_HANDLER, PEER_ACCEPTOR>
accept_strategy_type;
typedef ACE_Concurrency_Strategy<SVC_HANDLER>
concurrency_strategy_type;
typedef ACE_Scheduling_Strategy<SVC_HANDLER> scheduling_strategy_type;
typedef ACE_Acceptor <SVC_HANDLER, PEER_ACCEPTOR>
base_type;
// = Define some useful (old style) traits.
typedef ACE_Creation_Strategy<SVC_HANDLER> CREATION_STRATEGY;
typedef ACE_Accept_Strategy<SVC_HANDLER, PEER_ACCEPTOR> ACCEPT_STRATEGY;
typedef ACE_Concurrency_Strategy<SVC_HANDLER> CONCURRENCY_STRATEGY;
typedef ACE_Scheduling_Strategy<SVC_HANDLER> SCHEDULING_STRATEGY;
/// Default constructor.
ACE_Strategy_Acceptor (const ACE_TCHAR service_name[] = 0,
const ACE_TCHAR service_description[] = 0,
int use_select = 1,
int reuse_addr = 1);
/**
* Initialize the appropriate strategies for creation, passive
* connection acceptance, and concurrency, and then register {this}
* with the Reactor and listen for connection requests at the
* designated {local_addr}.
*/
ACE_Strategy_Acceptor (const typename PEER_ACCEPTOR::PEER_ADDR &local_addr,
ACE_Reactor * = ACE_Reactor::instance (),
ACE_Creation_Strategy<SVC_HANDLER> * = 0,
ACE_Accept_Strategy<SVC_HANDLER, PEER_ACCEPTOR> * = 0,
ACE_Concurrency_Strategy<SVC_HANDLER> * = 0,
ACE_Scheduling_Strategy<SVC_HANDLER> * = 0,
const ACE_TCHAR service_name[] = 0,
const ACE_TCHAR service_description[] = 0,
int use_select = 1,
int reuse_addr = 1);
/**
* Open the contained @c PEER_ACCEPTOR object to begin listening, and
* register with the specified reactor for accept events.
*
* The @c PEER_ACCEPTOR handle is put into non-blocking mode as a
* safeguard against the race condition that can otherwise occur
* between the time when the passive-mode socket handle is "ready"
* and when the actual @c accept call is made. During this
* interval, the client can shutdown the connection, in which case,
* the {accept} call can hang.
*
* @param local_addr The address to listen at.
* @param reactor Pointer to the ACE_Reactor instance to register
* this object with. The default is the singleton.
* @param flags Flags to control what mode an accepted socket
* will be put into after it is accepted. The only
* legal value for this argument is @c ACE_NONBLOCK,
* which enables non-blocking mode on the accepted
* peer stream object in @c SVC_HANDLER. The default
* is 0.
* @param use_select Affects behavior when called back by the reactor
* when a connection can be accepted. If non-zero,
* this object will accept all pending connections,
* instead of just the one that triggered the reactor
* callback. Uses ACE_OS::select() internally to
* detect any remaining acceptable connections.
* The default is 1.
* @param reuse_addr Passed to the @c PEER_ACCEPTOR::open() method with
* @p local_addr. Generally used to request that the
* OS allow reuse of the listen port. The default is 1.
*
* @retval 0 Success
* @retval -1 Failure, @c errno contains an error code.
*/
virtual int open (const typename PEER_ACCEPTOR::PEER_ADDR &local_addr,
ACE_Reactor *reactor,
int flags = 0,
int use_select = 1,
int reuse_addr = 1);
/**
* Initialize the appropriate strategies for creation, passive
* connection acceptance, and concurrency, and then register {this}
* with the Reactor and listen for connection requests at the
* designated {local_addr}.
*/
virtual int open (const typename PEER_ACCEPTOR::PEER_ADDR &,
ACE_Reactor * = ACE_Reactor::instance (),
ACE_Creation_Strategy<SVC_HANDLER> * = 0,
ACE_Accept_Strategy<SVC_HANDLER, PEER_ACCEPTOR> * =0,
ACE_Concurrency_Strategy<SVC_HANDLER> * = 0,
ACE_Scheduling_Strategy<SVC_HANDLER> * = 0,
const ACE_TCHAR *service_name = 0,
const ACE_TCHAR *service_description = 0,
int use_select = 1,
int reuse_addr = 1);
/// Close down the Strategy_Acceptor's resources.
virtual ~ACE_Strategy_Acceptor (void);
/// Return the underlying PEER_ACCEPTOR object.
virtual operator PEER_ACCEPTOR &() const;
/// Return the underlying PEER_ACCEPTOR object.
virtual PEER_ACCEPTOR &acceptor (void) const;
/// Returns the listening acceptor's {ACE_HANDLE}.
virtual ACE_HANDLE get_handle (void) const;
/// Dump the state of an object.
void dump (void) const;
/// Declare the dynamic allocation hooks.
ACE_ALLOC_HOOK_DECLARE;
// = Service management hooks.
/// This method delegates to the {Scheduling_Strategy}'s {suspend}
/// method.
virtual int suspend (void);
/// This method delegates to the {Scheduling_Strategy}'s {resume}
/// method.
virtual int resume (void);
protected:
/// Calls {handle_close} when dynamically unlinked.
virtual int fini (void);
/// Default version returns address info in {buf}.
virtual int info (ACE_TCHAR **buf, size_t) const;
// = The following three methods define the {Acceptor}'s strategies
// for creating, accepting, and activating {SVC_HANDLER}'s,
// respectively.
/**
* Bridge method for creating a {SVC_HANDLER}. The strategy for
* creating a {SVC_HANDLER} are configured into the Acceptor via
* it's {creation_strategy_}. The default is to create a new
* {SVC_HANDLER} if {sh} == 0, else {sh} is unchanged. However,
* subclasses can override this policy to perform {SVC_HANDLER}
* creation in any way that they like (such as creating subclass
* instances of {SVC_HANDLER}, using a singleton, dynamically
* linking the handler, etc.). Returns -1 on failure, else 0.
*/
virtual int make_svc_handler (SVC_HANDLER *&);
/**
* Bridge method for accepting the new connection into the
* {SVC_HANDLER}. The default behavior delegates to the
* {PEER_ACCEPTOR::accept} in the {Acceptor_Strategy}.
*/
virtual int accept_svc_handler (SVC_HANDLER *svc_handler);
/**
* Bridge method for activating a {SVC_HANDLER} with the appropriate
* concurrency strategy. The default behavior of this method is to
* activate the {SVC_HANDLER} by calling its {open} method (which
* allows the {SVC_HANDLER} to define its own concurrency strategy).
* However, subclasses can override this strategy to do more
* sophisticated concurrency activations (such as creating the
* {SVC_HANDLER} as an "active object" via multi-threading or
* multi-processing).
*/
virtual int activate_svc_handler (SVC_HANDLER *svc_handler);
// = Demultiplexing hooks.
/// Perform termination activities when {this} is removed from the
/// {Reactor}.
virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE,
ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK);
/// Handle SIGINT.
virtual int handle_signal (int signum, siginfo_t *, ucontext_t *);
// = These data members are "logically private" but are put in the
// protected part in case subclasses want to access them.
// = Strategy objects.
/// Creation strategy for an Acceptor.
CREATION_STRATEGY *creation_strategy_;
/// true if {Acceptor} created the creation strategy and thus should
/// delete it, else false.
bool delete_creation_strategy_;
/// Accept strategy for an {Acceptor}.
ACCEPT_STRATEGY *accept_strategy_;
/// true if {Acceptor} created the accept strategy and thus should delete
/// it, else false.
bool delete_accept_strategy_;
/// Concurrency strategy for an {Acceptor}.
CONCURRENCY_STRATEGY *concurrency_strategy_;
/// true if {Acceptor} created the concurrency strategy and thus should
/// delete it, else false.
bool delete_concurrency_strategy_;
/// Scheduling strategy for an {Acceptor}.
SCHEDULING_STRATEGY *scheduling_strategy_;
/// true if {Acceptor} created the scheduling strategy and thus should
/// delete it, else false.
bool delete_scheduling_strategy_;
// = Service information objects.
/// Name of the service.
ACE_TCHAR *service_name_;
/// Description of the service.
ACE_TCHAR *service_description_;
/// Address that the {Strategy_Acceptor} uses to listen for
/// connections.
typename PEER_ACCEPTOR::PEER_ADDR service_addr_;
};
/**
* @class ACE_Oneshot_Acceptor
*
* @brief Generic factory for passively connecting clients and creating
* exactly one service handler of the type SVC_HANDLER specified in the
* template.
*
* This class works similarly to the regular ACE_Acceptor, but
* with the following differences:
* -# ACE_Oneshot_Acceptor doesn't automatically register itself with the
* ACE_Reactor; the caller is expected to call the accept() method
* directly. Since a later call to accept() may require a reactor,
* the constructor and open() methods both accept an ACE_Reactor pointer
* which is saved in case it's needed in accept().
* -# ACE_Oneshot_Acceptor doesn't need an ACE_Creation_Strategy (because
* the user supplies the SVC_HANDLER) or an ACE_Accept_Strategy (because
* this class only accepts one connection and then removes all traces of
* itself from the ACE_Reactor if it was registered for asynchronous
* accepts).
*
* The usage model for ACE_Oneshot_Acceptor is:
* - Instantiate an object and establish its local address to listen at.
* This can be accomplished using either the address-accepting constructor
* (but there's no error indication) or the default constructor followed
* by a call to open().
* - Call the accept() method. This will attempt to accept a connection
* immediately. If there is no immediately available connection to accept,
* behavior is governed by the ACE_Synch_Options argument passed to open().
*/
template <typename SVC_HANDLER, typename PEER_ACCEPTOR>
class ACE_Oneshot_Acceptor : public ACE_Service_Object
{
public:
// Useful STL-style traits.
typedef typename PEER_ACCEPTOR::PEER_ADDR addr_type;
typedef PEER_ACCEPTOR acceptor_type;
typedef SVC_HANDLER handler_type;
typedef typename SVC_HANDLER::stream_type stream_type;
/// Constructor.
ACE_Oneshot_Acceptor (void);
/**
* Initialize the appropriate strategies for concurrency and then
* open the acceptor at the designated @a local_addr. Note
* that unlike ACE_Acceptor and ACE_Strategy_Acceptor, this
* method does NOT register this acceptor with the @a reactor at
* this point -- the @a reactor parameter is saved in case it's
* needed later.
*/
ACE_Oneshot_Acceptor (const typename PEER_ACCEPTOR::PEER_ADDR &local_addr,
ACE_Reactor *reactor = ACE_Reactor::instance (),
ACE_Concurrency_Strategy<SVC_HANDLER> * = 0);
/**
* Initialize the appropriate strategies for concurrency and then
* open the acceptor at the designated @a local_addr. Note
* that unlike ACE_Acceptor and ACE_Strategy_Acceptor, this
* method does NOT register this acceptor with the @a reactor at
* this point -- the @a reactor parameter is saved in case it's
* needed later.
*/
int open (const typename PEER_ACCEPTOR::PEER_ADDR &,
ACE_Reactor *reactor = ACE_Reactor::instance (),
ACE_Concurrency_Strategy<SVC_HANDLER> * = 0);
/// Close down the {Oneshot_Acceptor}.
virtual ~ACE_Oneshot_Acceptor (void);
// = Explicit factory operation.
/// Create a {SVC_HANDLER}, accept the connection into the
/// {SVC_HANDLER}, and activate the {SVC_HANDLER}.
virtual int accept (SVC_HANDLER * = 0,
typename PEER_ACCEPTOR::PEER_ADDR *remote_addr = 0,
const ACE_Synch_Options &synch_options = ACE_Synch_Options::defaults,
bool restart = true,
bool reset_new_handle = false);
/// Cancel a oneshot acceptor that was started asynchronously.
virtual int cancel (void);
/// Return the underlying {PEER_ACCEPTOR} object.
virtual operator PEER_ACCEPTOR &() const;
/// Return the underlying {PEER_ACCEPTOR} object.
virtual PEER_ACCEPTOR &acceptor (void) const;
/// Close down the {Oneshot_Acceptor}.
virtual int close (void);
/// Dump the state of an object.
void dump (void) const;
/// Declare the dynamic allocation hooks.
ACE_ALLOC_HOOK_DECLARE;
protected:
/**
* Bridge method for activating a {svc_handler} with the appropriate
* concurrency strategy. Default behavior is to activate the
* {SVC_HANDLER} as a "passive object." However, subclasses can
* override this strategy to do more sophisticated concurrency
* activations (such as creating the {SVC_HANDLER} as an "active
* object" via multi-threading or multi-processing).
*/
virtual int activate_svc_handler (SVC_HANDLER *svc_handler);
/// Factors out the code shared between the {accept} and
/// {handle_input} methods.
int shared_accept (SVC_HANDLER *svc_handler,
typename PEER_ACCEPTOR::PEER_ADDR *remote_addr,
ACE_Time_Value *timeout,
bool restart,
bool reset_new_handle);
// = Demultiplexing hooks.
/// Returns the listening acceptor's {ACE_HANDLE}.
virtual ACE_HANDLE get_handle (void) const;
/// Perform termination activities when {this} is removed from the
/// {reactor}.
virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE,
ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK);
/// Accept one connection from a client and activates the
/// SVC_HANDLER.
virtual int handle_input (ACE_HANDLE);
/// Called when an acceptor times out...
virtual int handle_timeout (const ACE_Time_Value &tv,
const void *arg);
// = Dynamic linking hooks.
/// Default version does no work and returns -1. Must be overloaded
/// by application developer to do anything meaningful.
virtual int init (int argc, ACE_TCHAR *argv[]);
/// Default version does no work and returns -1. Must be overloaded
/// by application developer to do anything meaningful.
virtual int fini (void);
/// Default version returns address info in {buf}.
virtual int info (ACE_TCHAR **, size_t) const;
// = Service management hooks.
/// Default version does no work and returns -1. Must be overloaded
/// by application developer to do anything meaningful.
virtual int suspend (void);
/// Default version does no work and returns -1. Must be overloaded
/// by application developer to do anything meaningful.
virtual int resume (void);
private:
/**
* Insert ourselves into the {ACE_Reactor} so that we can continue
* accepting this connection asynchronously. This method should NOT
* be called by developers directly.
*/
int register_handler (SVC_HANDLER *svc_handler,
const ACE_Synch_Options &options,
bool restart);
/// Hold the svc_handler_ across asynchrony boundaries.
SVC_HANDLER *svc_handler_;
/// Hold the restart flag across asynchrony boundaries.
bool restart_;
/// Factory that establishes connections passively.
PEER_ACCEPTOR peer_acceptor_;
/// Concurrency strategy for an Acceptor.
ACE_Concurrency_Strategy<SVC_HANDLER> *concurrency_strategy_;
/// true if Acceptor created the concurrency strategy and thus should
/// delete it, else false.
bool delete_concurrency_strategy_;
};
ACE_END_VERSIONED_NAMESPACE_DECL
#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
#include "ace/Acceptor.cpp"
#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
#pragma implementation ("Acceptor.cpp")
#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
#include /**/ "ace/post.h"
#endif /* ACE_ACCEPTOR_H */

View File

@@ -0,0 +1,134 @@
#include "ace/Activation_Queue.h"
#if !defined (__ACE_INLINE__)
#include "ace/Activation_Queue.inl"
#endif /* __ACE_INLINE__ */
#include "ace/Log_Category.h"
#include "ace/Method_Request.h"
#include "ace/Malloc_Base.h"
#include "ace/Time_Value.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
void
ACE_Activation_Queue::dump (void) const
{
#if defined (ACE_HAS_DUMP)
ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
ACELIB_DEBUG ((LM_DEBUG,
ACE_TEXT ("delete_queue_ = %d\n"),
this->delete_queue_));
ACELIB_DEBUG ((LM_INFO, ACE_TEXT ("queue_:\n")));
if (this->queue_)
this->queue_->dump();
else
//FUZZ: disable check_for_NULL
ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("(NULL)\n")));
//FUZZ: enable check_for_NULL
ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
#endif /* ACE_HAS_DUMP */
}
ACE_Activation_Queue::ACE_Activation_Queue (ACE_Message_Queue<ACE_SYNCH> *new_queue,
ACE_Allocator *alloc,
ACE_Allocator *db_alloc)
: delete_queue_ (false)
, allocator_(alloc)
, data_block_allocator_(db_alloc)
{
if (this->allocator_ == 0)
this->allocator_ = ACE_Allocator::instance ();
if (new_queue)
this->queue_ = new_queue;
else
{
ACE_NEW (this->queue_,
ACE_Message_Queue<ACE_SYNCH>);
this->delete_queue_ = true;
}
}
void
ACE_Activation_Queue::queue (ACE_Message_Queue<ACE_SYNCH> *q)
{
// Destroy the internal queue if one exist.
if (this->delete_queue_)
{
// Destroy the current queue.
delete this->queue_;
// Set the flag to false. NOTE that the delete_queue_ flag is a
// flag used to only indicate whether or not if an internal
// ACE_Message_Queue has been created, therefore, it will not
// affect the user if the user decided to replace the queue with
// their own queue no matter how many time they call on this
// function.
this->delete_queue_ = false;
}
queue_ = q;
}
ACE_Activation_Queue::~ACE_Activation_Queue (void)
{
if (this->delete_queue_)
delete this->queue_;
}
ACE_Method_Request *
ACE_Activation_Queue::dequeue (ACE_Time_Value *tv)
{
ACE_Message_Block *mb = 0;
// Dequeue the message.
if (this->queue_->dequeue_head (mb, tv) != -1)
{
// Get the next <Method_Request>.
ACE_Method_Request *mr =
reinterpret_cast<ACE_Method_Request *> (mb->base ());
// Delete the message block.
mb->release ();
return mr;
}
else
return 0;
}
int
ACE_Activation_Queue::enqueue (ACE_Method_Request *mr,
ACE_Time_Value *tv)
{
ACE_Message_Block *mb = 0;
// We pass sizeof (*mr) here so that flow control will work
// correctly. Since we also pass <mr> note that no unnecessary
// memory is actually allocated -- just the size field is set.
ACE_NEW_MALLOC_RETURN (mb,
static_cast<ACE_Message_Block *> (this->allocator_->malloc (sizeof (ACE_Message_Block))),
ACE_Message_Block (sizeof (*mr), // size
ACE_Message_Block::MB_DATA, // type
0, // cont
(char *) mr, // data
0, // allocator
0, // locking strategy
mr->priority (), // priority
ACE_Time_Value::zero, // execution time
ACE_Time_Value::max_time, // absolute time of deadline
this->data_block_allocator_, // data_block allocator
this->allocator_), // message_block allocator
-1);
// Enqueue in priority order.
int const result = this->queue_->enqueue_prio (mb, tv);
// Free ACE_Message_Block if enqueue_prio failed.
if (result == -1)
ACE_DES_FREE (mb, this->allocator_->free, ACE_Message_Block);
return result;
}
ACE_END_VERSIONED_NAMESPACE_DECL

View File

@@ -0,0 +1,168 @@
// -*- C++ -*-
//=============================================================================
/**
* @file Activation_Queue.h
*
* @author Andres Kruse <Andres.Kruse@cern.ch>
* @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
*/
//=============================================================================
#ifndef ACE_ACTIVATION_QUEUE_H
#define ACE_ACTIVATION_QUEUE_H
#include /**/ "ace/pre.h"
#include /**/ "ace/ACE_export.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "ace/Message_Queue.h"
#include "ace/Copy_Disabled.h"
#include "ace/Condition_Thread_Mutex.h"
/// Define to be compatible with the terminology in the POSA2 book!
#define ACE_Activation_List ACE_Activation_Queue
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
class ACE_Method_Request;
/**
* @class ACE_Activation_Queue
*
* @brief
* Reifies a method into a request. Subclasses typically
* represent necessary state and behavior.
*
* Maintains a priority-ordered queue of ACE_Method_Request objects.
* A scheduler class (often derived from ACE_Task) subsequently removes
* each method request and invokes its @c call() method.
*
* This class is discussed in depth in the Active Object chapter
* of POSA2. In that book, it is referred to as an Activation List.
*
* @sa ACE_Method_Request
*/
class ACE_Export ACE_Activation_Queue
{
public:
/// Constructor.
/**
* Initializes a new activation queue.
*
* @param new_queue The activation queue uses an ACE_Message_Queue to
* queue and order the method requests. If this argument
* is 0, a new ACE_Message_Queue is created for this
* object's use and will be deleted when this object is
* destroyed. If a non-zero pointer is supplied, the
* passed object will be used and will not be deleted when
* this object is destroyed. If an ACE_Task is being created
* to act as the scheduler, for instance, its
* ACE_Message_Queue pointer can be passed to this object.
* @param alloc Optional, the allocator to use when allocating
* ACE_Message_Block instances that wrap the method requests
* queued to this activation queue. Defaults to
* ACE_Allocator::instance().
* @param db_alloc Optional, the allocator to use when allocating
* data blocks for the ACE_Message_Block instances that
* wrap the method requests queued to this activation queue.
* Defaults to ACE_Allocator::instance().
*/
ACE_Activation_Queue (ACE_Message_Queue<ACE_SYNCH> *new_queue = 0,
ACE_Allocator *alloc = 0,
ACE_Allocator *db_alloc = 0);
/// Destructor.
virtual ~ACE_Activation_Queue (void);
// = Activate Queue operations.
/// Dequeue the next available ACE_Method_Request.
/**
* @param tv If 0, the method will block until a method request is
* available, else will wait until the absolute time specified
* in the referenced ACE_Time_Value. This method will return,
* earlier, however, if queue is closed, deactivated, or when
* a signal occurs.
*
* @retval Pointer to the dequeued ACE_Method_Request object.
* @retval 0 an error occurs; errno contains further information. If
* the specified timeout elapses, errno will be @c EWOULDBLOCK.
*/
ACE_Method_Request *dequeue (ACE_Time_Value *tv = 0);
/// Enqueue the ACE_Method_Request in priority order.
/**
* The priority of the method request is obtained via the @c priority()
* method of the queued method request. Priority ordering is determined
* by the ACE_Message_Queue class; 0 is the lowest priority.
*
* @param new_method_request Pointer to the ACE_Method_Request object to
* queue. This object's @c priority() method is called to obtain
* the priority.
* @param tv If 0, the method will block until the method request can
* be queued, else will wait until the absolute time specified
* in the referenced ACE_Time_Value. This method will return,
* earlier, however, if queue is closed, deactivated, or when
* a signal occurs.
*
* @retval >0 The number of method requests on the queue after adding
* the specified request.
* @retval -1 if an error occurs; errno contains further information. If
* the specified timeout elapses, errno will be @c EWOULDBLOCK.
*/
int enqueue (ACE_Method_Request *new_method_request, ACE_Time_Value *tv = 0);
/// Get the current number of method objects in the queue.
size_t method_count (void) const;
/// Returns 1 if the queue is empty, 0 otherwise.
int is_empty (void) const;
/// Returns 1 if the queue is full, 0 otherwise.
int is_full (void) const;
/// Dump the state of an request.
void dump (void) const;
/// Get a pointer to the underlying queue.
ACE_Message_Queue<ACE_SYNCH> *queue (void) const;
/// Set the pointer to the underlying queue.
void queue (ACE_Message_Queue<ACE_SYNCH> *q);
/// Declare the dynamic allocation hooks.
ACE_ALLOC_HOOK_DECLARE;
protected:
/// Stores the Method_Requests.
ACE_Message_Queue<ACE_SYNCH> *queue_;
/// Keeps track of whether we need to delete the queue.
bool delete_queue_;
private:
/// Allocation strategy of the queue.
ACE_Allocator *allocator_;
/// Allocation strategy of the message blocks.
ACE_Allocator *data_block_allocator_;
ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Activation_Queue &))
ACE_UNIMPLEMENTED_FUNC (ACE_Activation_Queue (const ACE_Activation_Queue &))
};
ACE_END_VERSIONED_NAMESPACE_DECL
#if defined (__ACE_INLINE__)
#include "ace/Activation_Queue.inl"
#endif /* __ACE_INLINE__ */
#include /**/ "ace/post.h"
#endif /* ACE_ACTIVATION_QUEUE_H */

View File

@@ -0,0 +1,31 @@
// -*- C++ -*-
//
// $Id: Activation_Queue.inl 80826 2008-03-04 14:51:23Z wotte $
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
ACE_INLINE size_t
ACE_Activation_Queue::method_count (void) const
{
return queue_->message_count ();
}
ACE_INLINE int
ACE_Activation_Queue::is_full (void) const
{
return queue_->is_full ();
}
ACE_INLINE int
ACE_Activation_Queue::is_empty (void) const
{
return queue_->is_empty ();
}
ACE_INLINE ACE_Message_Queue<ACE_SYNCH> *
ACE_Activation_Queue::queue (void) const
{
return queue_;
}
ACE_END_VERSIONED_NAMESPACE_DECL

View File

@@ -0,0 +1,7 @@
// $Id: Active_Map_Manager.cpp 91286 2010-08-05 09:04:31Z johnnyw $
#include "ace/Active_Map_Manager.h"
#if !defined (__ACE_INLINE__)
#include "ace/Active_Map_Manager.inl"
#endif /* __ACE_INLINE__ */

View File

@@ -0,0 +1,116 @@
/* -*- C++ -*- */
//=============================================================================
/**
* @file Active_Map_Manager.h
*
* $Id: Active_Map_Manager.h 93359 2011-02-11 11:33:12Z mcorino $
*
* @author Irfan Pyarali
*/
//=============================================================================
#ifndef ACE_ACTIVE_MAP_MANAGER_H
#define ACE_ACTIVE_MAP_MANAGER_H
#include /**/ "ace/pre.h"
#include /**/ "ace/ACE_export.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "ace/Basic_Types.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
/**
* @class ACE_Active_Map_Manager_Key
*
* @brief Key used in the Active Object Map.
*
* This key keeps information of the index and the generation
* count of the slot it represents. Since the index information
* is part of the key, lookups are super fast and predictable,
*/
class ACE_Export ACE_Active_Map_Manager_Key
{
public:
/// Default constructor.
ACE_Active_Map_Manager_Key (void);
/**
* Constructor given the @a slot_index and @a slot_generation number.
* This is useful once the user has somehow recovered the
* @a slot_index and @a slot_generation number from the client.
*/
ACE_Active_Map_Manager_Key (ACE_UINT32 slot_index,
ACE_UINT32 slot_generation);
/// Get the slot_index.
ACE_UINT32 slot_index (void) const;
/// Set the slot_index.
void slot_index (ACE_UINT32 i);
/// Get the slot_generation number.
ACE_UINT32 slot_generation (void) const;
/// Set the slot_generation number.
void slot_generation (ACE_UINT32 g);
/// Size required to store information about active key.
static size_t size (void);
/// Recover state of active key from @a data. User must make sure
/// that @a data encoded using the encode() method.
void decode (const void *data);
/// Encode state of the active key into @a data. @a data must be as
/// big as the value returned from size().
void encode (void *data) const;
/// Compare keys.
bool operator== (const ACE_Active_Map_Manager_Key &rhs) const;
bool operator!= (const ACE_Active_Map_Manager_Key &rhs) const;
// = This really should be protected but because of template
// friends, they are not.
/// Increment the slot_generation number.
void increment_slot_generation_count (void);
private:
/**
* @brief Data for the Active Object Map Key.
*
* This separate structure makes it easier to manage copying
* the index and the generation to and from the user buffer.
*
*/
struct key_data
{
/// Slot index in the active map.
ACE_UINT32 slot_index_;
/// Slot generation number of @c slot_index_ slot in the active map.
ACE_UINT32 slot_generation_;
};
/// Data for the Active Object Map Key.
key_data key_data_;
};
ACE_END_VERSIONED_NAMESPACE_DECL
#if defined (__ACE_INLINE__)
#include "ace/Active_Map_Manager.inl"
#endif /* __ACE_INLINE__ */
// Include the templates here.
#include "ace/Active_Map_Manager_T.h"
#include /**/ "ace/post.h"
#endif /* ACE_ACTIVE_MAP_MANAGER_H */

View File

@@ -0,0 +1,95 @@
// -*- C++ -*-
//
// $Id: Active_Map_Manager.inl 80826 2008-03-04 14:51:23Z wotte $
#include "ace/OS_NS_string.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
ACE_INLINE
ACE_Active_Map_Manager_Key::ACE_Active_Map_Manager_Key (void)
{
// If you change ~0, please change ACE_Map_Manager::free_list_id()
// accordingly.
this->key_data_.slot_index_ = (ACE_UINT32) ~0;
this->key_data_.slot_generation_ = 0;
}
ACE_INLINE
ACE_Active_Map_Manager_Key::ACE_Active_Map_Manager_Key (ACE_UINT32 slot_index,
ACE_UINT32 slot_generation)
{
this->key_data_.slot_index_ = slot_index;
this->key_data_.slot_generation_ = slot_generation;
}
ACE_INLINE ACE_UINT32
ACE_Active_Map_Manager_Key::slot_index (void) const
{
return this->key_data_.slot_index_;
}
ACE_INLINE ACE_UINT32
ACE_Active_Map_Manager_Key::slot_generation (void) const
{
return this->key_data_.slot_generation_;
}
ACE_INLINE bool
ACE_Active_Map_Manager_Key::operator== (const ACE_Active_Map_Manager_Key &rhs) const
{
return
this->key_data_.slot_index_ == rhs.key_data_.slot_index_ &&
this->key_data_.slot_generation_ == rhs.key_data_.slot_generation_;
}
ACE_INLINE bool
ACE_Active_Map_Manager_Key::operator!= (const ACE_Active_Map_Manager_Key &rhs) const
{
return !this->operator== (rhs);
}
ACE_INLINE void
ACE_Active_Map_Manager_Key::slot_index (ACE_UINT32 i)
{
this->key_data_.slot_index_ = i;
}
ACE_INLINE void
ACE_Active_Map_Manager_Key::slot_generation (ACE_UINT32 g)
{
this->key_data_.slot_generation_ = g;
}
ACE_INLINE void
ACE_Active_Map_Manager_Key::increment_slot_generation_count (void)
{
++this->key_data_.slot_generation_;
}
/* static */
ACE_INLINE size_t
ACE_Active_Map_Manager_Key::size (void)
{
return sizeof (ACE_UINT32) + sizeof (ACE_UINT32);
}
ACE_INLINE void
ACE_Active_Map_Manager_Key::decode (const void *data)
{
// Copy the information from the user buffer into the key.
ACE_OS::memcpy (&this->key_data_,
data,
sizeof this->key_data_);
}
ACE_INLINE void
ACE_Active_Map_Manager_Key::encode (void *data) const
{
// Copy the key data to the user buffer.
ACE_OS::memcpy (data,
&this->key_data_,
sizeof this->key_data_);
}
ACE_END_VERSIONED_NAMESPACE_DECL

View File

@@ -0,0 +1,22 @@
// $Id: Active_Map_Manager_T.cpp 80826 2008-03-04 14:51:23Z wotte $
#ifndef ACE_ACTIVE_MAP_MANAGER_T_CPP
#define ACE_ACTIVE_MAP_MANAGER_T_CPP
#include "ace/Active_Map_Manager_T.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#if !defined (__ACE_INLINE__)
#include "ace/Active_Map_Manager_T.inl"
#endif /* __ACE_INLINE__ */
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
ACE_ALLOC_HOOK_DEFINE(ACE_Active_Map_Manager)
ACE_END_VERSIONED_NAMESPACE_DECL
#endif /* ACE_ACTIVE_MAP_MANAGER_T_CPP */

View File

@@ -0,0 +1,211 @@
/* -*- C++ -*- */
//=============================================================================
/**
* @file Active_Map_Manager_T.h
*
* $Id: Active_Map_Manager_T.h 84316 2009-02-03 19:46:05Z johnnyw $
*
* @author Irfan Pyarali
*/
//=============================================================================
#ifndef ACE_ACTIVE_MAP_MANAGER_T_H
#define ACE_ACTIVE_MAP_MANAGER_T_H
#include /**/ "ace/pre.h"
#include "ace/Map_Manager.h"
#include "ace/Active_Map_Manager.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "ace/Null_Mutex.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
/**
* @class ACE_Active_Map_Manager
*
* @brief Define a map abstraction that associates system generated
* keys with user specified values.
*
* Since the key is system generated, searches are very fast and
* take a constant amount of time.
*/
template <class T>
class ACE_Active_Map_Manager : public ACE_Map_Manager<ACE_Active_Map_Manager_Key, T, ACE_Null_Mutex>
{
public:
// = Traits.
typedef ACE_Active_Map_Manager_Key key_type;
typedef T mapped_type;
typedef ACE_Map_Entry<ACE_Active_Map_Manager_Key, T> ENTRY;
typedef ACE_Map_Iterator<ACE_Active_Map_Manager_Key, T, ACE_Null_Mutex> ITERATOR;
typedef ACE_Map_Reverse_Iterator<ACE_Active_Map_Manager_Key, T, ACE_Null_Mutex> REVERSE_ITERATOR;
typedef ENTRY entry;
typedef ITERATOR iterator;
typedef REVERSE_ITERATOR reverse_iterator;
// = Initialization and termination methods.
/// Initialize a Active_Map_Manager with the ACE_DEFAULT_MAP_SIZE.
ACE_Active_Map_Manager (ACE_Allocator *alloc = 0);
/// Initialize a Active_Map_Manager with @a size entries.
ACE_Active_Map_Manager (size_t size,
ACE_Allocator *alloc = 0);
/// Close down a Active_Map_Manager and release dynamically
/// allocated resources.
~ACE_Active_Map_Manager (void);
/// Initialize a Active_Map_Manager with size @a length.
int open (size_t length = ACE_DEFAULT_MAP_SIZE,
ACE_Allocator *alloc = 0);
/// Close down a Active_Map_Manager and release dynamically
/// allocated resources.
int close (void);
/// Add @a value to the map, and the corresponding key produced by the
/// Active_Map_Manager is returned through @a key.
int bind (const T &value,
ACE_Active_Map_Manager_Key &key);
/// Add @a value to the map. The user does not care about the
/// corresponding key produced by the Active_Map_Manager.
int bind (const T &value);
/**
* Reserves a slot in the internal structure and returns the key and
* a pointer to the value. User should place their @a value into
* @a internal_value. This method is useful in reducing the number
* of copies required in some cases. Note that @a internal_value is
* only a temporary pointer and will change when the map resizes.
* Therefore, the user should use the pointer immediately and not
* hold on to it.
*/
int bind (ACE_Active_Map_Manager_Key &key,
T *&internal_value);
/// Reassociate @a key with @a value. The function fails if @a key is
/// not in the map.
int rebind (const ACE_Active_Map_Manager_Key &key,
const T &value);
/**
* Reassociate @a key with @a value, storing the old value into the
* "out" parameter @a old_value. The function fails if @a key is not
* in the map.
*/
int rebind (const ACE_Active_Map_Manager_Key &key,
const T &value,
T &old_value);
/**
* Reassociate @a key with @a value, storing the old key and value
* into the "out" parameter @a old_key and @a old_value. The function
* fails if @a key is not in the map.
*/
int rebind (const ACE_Active_Map_Manager_Key &key,
const T &value,
ACE_Active_Map_Manager_Key &old_key,
T &old_value);
/// Locate @a value associated with @a key.
int find (const ACE_Active_Map_Manager_Key &key,
T &value) const;
/// Is @a key in the map?
int find (const ACE_Active_Map_Manager_Key &key) const;
/**
* Locate @a value associated with @a key. The value is returned via
* @a internal_value and hence a copy is saved. Note that
* @a internal_value is only a temporary pointer and will change when
* the map resizes. Therefore, the user should use the pointer
* immediately and not hold on to it.
*/
int find (const ACE_Active_Map_Manager_Key &key,
T *&internal_value) const;
// Creates a key. User should place their @a value into
// <*internal_value>. This method is useful in reducing the number
// of copies required in some cases.
/// Remove @a key from the map.
int unbind (const ACE_Active_Map_Manager_Key &key);
/// Remove @a key from the map, and return the @a value associated with
/// @a key.
int unbind (const ACE_Active_Map_Manager_Key &key,
T &value);
/**
* Locate @a value associated with @a key. The value is returned via
* @a internal_value and hence a copy is saved. Note that
* @a internal_value is only a temporary pointer and will change when
* the map resizes or when this slot is reused. Therefore, the user
* should use the pointer immediately and not hold on to it.
*/
int unbind (const ACE_Active_Map_Manager_Key &key,
T *&internal_value);
/// Return the current size of the map.
size_t current_size (void) const;
/// Return the total size of the map.
size_t total_size (void) const;
/// Returns a key that cannot be found in the map.
static const ACE_Active_Map_Manager_Key npos (void);
/// Dump the state of an object.
void dump (void) const;
// = STL styled iterator factory functions.
/// Return forward iterator.
ACE_Map_Iterator<ACE_Active_Map_Manager_Key, T, ACE_Null_Mutex> begin (void);
ACE_Map_Iterator<ACE_Active_Map_Manager_Key, T, ACE_Null_Mutex> end (void);
/// Return reverse iterator.
ACE_Map_Reverse_Iterator<ACE_Active_Map_Manager_Key, T, ACE_Null_Mutex> rbegin (void);
ACE_Map_Reverse_Iterator<ACE_Active_Map_Manager_Key, T, ACE_Null_Mutex> rend (void);
/// Declare the dynamic allocation hooks.
ACE_ALLOC_HOOK_DECLARE;
protected:
/// Private base class
typedef ACE_Map_Manager<ACE_Active_Map_Manager_Key, T, ACE_Null_Mutex> ACE_AMM_BASE;
private:
// = Disallow these operations.
ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Active_Map_Manager<T> &))
ACE_UNIMPLEMENTED_FUNC (ACE_Active_Map_Manager (const ACE_Active_Map_Manager<T> &))
};
ACE_END_VERSIONED_NAMESPACE_DECL
#if defined (__ACE_INLINE__)
#include "ace/Active_Map_Manager_T.inl"
#endif /* __ACE_INLINE__ */
#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
#include "ace/Active_Map_Manager_T.cpp"
#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
#pragma implementation ("Active_Map_Manager_T.cpp")
#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
#include /**/ "ace/post.h"
#endif /* ACE_ACTIVE_MAP_MANAGER_T_H */

View File

@@ -0,0 +1,311 @@
// -*- C++ -*-
//
// $Id: Active_Map_Manager_T.inl 80826 2008-03-04 14:51:23Z wotte $
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
template <class T> ACE_INLINE int
ACE_Active_Map_Manager<T>::bind (ACE_Active_Map_Manager_Key &key,
T *&internal_value)
{
ACE_UINT32 slot_index;
int result = this->next_free (slot_index);
if (result == 0)
{
// Move from free list to occupied list
this->move_from_free_list_to_occupied_list (slot_index);
// Reset the key.
this->search_structure_[slot_index].ext_id_.increment_slot_generation_count ();
this->search_structure_[slot_index].ext_id_.slot_index (slot_index);
// Copy the key for the user.
key = this->search_structure_[slot_index].ext_id_;
// This is where the user should place the value.
internal_value = &this->search_structure_[slot_index].int_id_;
// Update the current size.
++this->cur_size_;
}
return result;
}
template <class T> ACE_INLINE int
ACE_Active_Map_Manager<T>::bind (const T &value,
ACE_Active_Map_Manager_Key &key)
{
T *internal_value = 0;
int result = this->bind (key,
internal_value);
if (result == 0)
{
// Store new value.
*internal_value = value;
}
return result;
}
template <class T> ACE_INLINE int
ACE_Active_Map_Manager<T>::bind (const T &value)
{
ACE_Active_Map_Manager_Key key;
return this->bind (value, key);
}
template <class T> ACE_INLINE int
ACE_Active_Map_Manager<T>::find (const ACE_Active_Map_Manager_Key &key,
T *&internal_value) const
{
ACE_UINT32 slot_index = key.slot_index ();
ACE_UINT32 slot_generation = key.slot_generation ();
if (slot_index > this->total_size_ ||
#if defined (ACE_HAS_LAZY_MAP_MANAGER)
this->search_structure_[slot_index].free_ ||
#endif /* ACE_HAS_LAZY_MAP_MANAGER */
this->search_structure_[slot_index].ext_id_.slot_generation () != slot_generation ||
this->search_structure_[slot_index].ext_id_.slot_index () ==
(ACE_UINT32)this->free_list_id ())
{
return -1;
}
else
{
// This is where the user value is.
internal_value = &this->search_structure_[slot_index].int_id_;
}
return 0;
}
template <class T> ACE_INLINE int
ACE_Active_Map_Manager<T>::find (const ACE_Active_Map_Manager_Key &key) const
{
T *internal_value = 0;
return this->find (key,
internal_value);
}
template <class T> ACE_INLINE int
ACE_Active_Map_Manager<T>::find (const ACE_Active_Map_Manager_Key &key,
T &value) const
{
T *internal_value = 0;
int result = this->find (key,
internal_value);
if (result == 0)
value = *internal_value;
return result;
}
template <class T> ACE_INLINE int
ACE_Active_Map_Manager<T>::rebind (const ACE_Active_Map_Manager_Key &key,
const T &value)
{
int result = this->find (key);
if (result == 0)
{
// Store new value.
this->search_structure_[key.slot_index ()].int_id_ = value;
}
return result;
}
template <class T> ACE_INLINE int
ACE_Active_Map_Manager<T>::rebind (const ACE_Active_Map_Manager_Key &key,
const T &value,
T &old_value)
{
int result = this->find (key);
if (result == 0)
{
// Copy old value.
old_value = this->search_structure_[key.slot_index ()].int_id_;
// Store new value.
this->search_structure_[key.slot_index ()].int_id_ = value;
}
return result;
}
template <class T> ACE_INLINE int
ACE_Active_Map_Manager<T>::rebind (const ACE_Active_Map_Manager_Key &key,
const T &value,
ACE_Active_Map_Manager_Key &old_key,
T &old_value)
{
int result = this->find (key);
if (result == 0)
{
// Copy old key.
old_key = this->search_structure_[key.slot_index ()].ext_id_;
// Copy old value.
old_value = this->search_structure_[key.slot_index ()].int_id_;
// Store new value.
this->search_structure_[key.slot_index ()].int_id_ = value;
}
return result;
}
template <class T> ACE_INLINE int
ACE_Active_Map_Manager<T>::unbind (const ACE_Active_Map_Manager_Key &key,
T *&internal_value)
{
int result = this->find (key,
internal_value);
if (result == 0)
{
ACE_UINT32 slot_index = key.slot_index ();
#if defined (ACE_HAS_LAZY_MAP_MANAGER)
//
// In the case of lazy map managers, the movement of free slots
// from the occupied list to the free list is delayed until we
// run out of free slots in the free list.
//
this->search_structure_[slot_index].free_ = 1;
#else
// Move from occupied list to free list.
this->move_from_occupied_list_to_free_list (slot_index);
#endif /* ACE_HAS_LAZY_MAP_MANAGER */
// Reset the slot_index. This will tell us that this entry is free.
this->search_structure_[slot_index].ext_id_.slot_index (this->free_list_id ());
// Update the current size.
--this->cur_size_;
}
return result;
}
template <class T> ACE_INLINE int
ACE_Active_Map_Manager<T>::unbind (const ACE_Active_Map_Manager_Key &key,
T &value)
{
T *internal_value;
int result = this->unbind (key,
internal_value);
if (result == 0)
{
// Copy old value.
value = *internal_value;
}
return result;
}
template <class T> ACE_INLINE int
ACE_Active_Map_Manager<T>::unbind (const ACE_Active_Map_Manager_Key &key)
{
T *internal_value;
return this->unbind (key,
internal_value);
}
template <class T> ACE_INLINE
ACE_Active_Map_Manager<T>::ACE_Active_Map_Manager (ACE_Allocator *alloc)
: ACE_AMM_BASE (alloc)
{
}
template <class T> ACE_INLINE
ACE_Active_Map_Manager<T>::ACE_Active_Map_Manager (size_t size,
ACE_Allocator *alloc)
: ACE_AMM_BASE (size,
alloc)
{
}
template <class T> ACE_INLINE
ACE_Active_Map_Manager<T>::~ACE_Active_Map_Manager (void)
{
}
template <class T> ACE_INLINE int
ACE_Active_Map_Manager<T>::open (size_t length,
ACE_Allocator *alloc)
{
return ACE_AMM_BASE::open (length, alloc);
}
template <class T> ACE_INLINE int
ACE_Active_Map_Manager<T>::close (void)
{
return ACE_AMM_BASE::close ();
}
template <class T> ACE_INLINE size_t
ACE_Active_Map_Manager<T>::current_size (void) const
{
return ACE_AMM_BASE::current_size ();
}
template <class T> ACE_INLINE size_t
ACE_Active_Map_Manager<T>::total_size (void) const
{
return ACE_AMM_BASE::total_size ();
}
/* static */
template <class T> ACE_INLINE const ACE_Active_Map_Manager_Key
ACE_Active_Map_Manager<T>::npos (void)
{
return ACE_Active_Map_Manager_Key (~0, ~0);
}
template <class T> ACE_INLINE void
ACE_Active_Map_Manager<T>::dump (void) const
{
#if defined (ACE_HAS_DUMP)
ACE_AMM_BASE::dump ();
#endif /* ACE_HAS_DUMP */
}
template <class T> ACE_Map_Iterator<ACE_Active_Map_Manager_Key, T, ACE_Null_Mutex>
ACE_Active_Map_Manager<T>::begin (void)
{
return ACE_AMM_BASE::begin ();
}
template <class T> ACE_INLINE ACE_Map_Iterator<ACE_Active_Map_Manager_Key, T, ACE_Null_Mutex>
ACE_Active_Map_Manager<T>::end (void)
{
return ACE_AMM_BASE::end ();
}
template <class T> ACE_INLINE ACE_Map_Reverse_Iterator<ACE_Active_Map_Manager_Key, T, ACE_Null_Mutex>
ACE_Active_Map_Manager<T>::rbegin (void)
{
return ACE_AMM_BASE::rbegin ();
}
template <class T> ACE_INLINE ACE_Map_Reverse_Iterator<ACE_Active_Map_Manager_Key, T, ACE_Null_Mutex>
ACE_Active_Map_Manager<T>::rend (void)
{
return ACE_AMM_BASE::rend ();
}
ACE_END_VERSIONED_NAMESPACE_DECL

View File

@@ -0,0 +1,65 @@
#include "ace/Addr.h"
#if !defined (__ACE_INLINE__)
#include "ace/Addr.inl"
#endif /* __ACE_INLINE__ */
#include "ace/Log_Category.h"
#include "ace/os_include/sys/os_socket.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
// Note: this object requires static construction and destruction.
/* static */
const ACE_Addr ACE_Addr::sap_any (AF_ANY, -1);
ACE_ALLOC_HOOK_DEFINE(ACE_Addr)
// Initializes instance variables. Note that 0 is an unspecified
// protocol family type...
ACE_Addr::ACE_Addr (int type, int size) :
addr_type_ (type),
addr_size_ (size)
{
}
ACE_Addr::~ACE_Addr (void)
{
}
void *
ACE_Addr::get_addr (void) const
{
return 0;
}
void
ACE_Addr::set_addr (const void *, int)
{
}
// Initializes instance variables.
void
ACE_Addr::base_set (int type, int size)
{
this->addr_type_ = type;
this->addr_size_ = size;
}
void
ACE_Addr::dump (void) const
{
#if defined (ACE_HAS_DUMP)
ACE_TRACE ("ACE_Addr::dump");
ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("addr_type_ = %d"), this->addr_type_));
ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("\naddr_size_ = %d"), this->addr_size_));
ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
#endif /* ACE_HAS_DUMP */
}
ACE_END_VERSIONED_NAMESPACE_DECL

View File

@@ -0,0 +1,101 @@
// -*- C++ -*-
//=============================================================================
/**
* @file Addr.h
*
* @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
*/
//=============================================================================
#ifndef ACE_ADDR_H
#define ACE_ADDR_H
#include /**/ "ace/pre.h"
#include /**/ "ace/ACE_export.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
/**
* @class ACE_Addr
*
* @brief Defines the base class for the "address family independent"
* address format.
*/
class ACE_Export ACE_Addr
{
public:
// = Initialization and termination methods.
/// Initializes instance variables.
ACE_Addr (int type = -1, int size = -1);
/// Destructor.
virtual ~ACE_Addr (void);
// = Get/set the size of the address.
/// Return the size of the address.
int get_size (void) const;
/// Sets the size of the address.
void set_size (int size);
// = Get/set the type of the address.
/// Get the type of the address.
int get_type (void) const;
/// Set the type of the address.
void set_type (int type);
/// Return a pointer to the address.
virtual void *get_addr (void) const;
/// Set a pointer to the address.
virtual void set_addr (const void *, int len);
// = Equality/inequality tests
/// Check for address equality.
bool operator == (const ACE_Addr &sap) const;
/// Check for address inequality.
bool operator != (const ACE_Addr &sap) const;
/// Initializes instance variables.
void base_set (int type, int size);
/// Wild-card address.
static const ACE_Addr sap_any;
/// Returns a hash value. This should be overwritten by a subclass
/// that can produce a better hash value.
virtual unsigned long hash (void) const;
/// Dump the state of an object.
void dump (void) const;
/// Declare the dynamic allocation hooks.
ACE_ALLOC_HOOK_DECLARE;
protected:
/// e.g., AF_UNIX, AF_INET, AF_SPIPE, etc.
int addr_type_;
/// Number of bytes in the address.
int addr_size_;
};
ACE_END_VERSIONED_NAMESPACE_DECL
#if defined (__ACE_INLINE__)
#include "ace/Addr.inl"
#endif /* __ACE_INLINE__ */
#include /**/ "ace/post.h"
#endif /* ACE_ADDR_H */

View File

@@ -0,0 +1,57 @@
// -*- C++ -*-
//
// $Id: Addr.inl 87295 2009-11-02 14:45:59Z johnnyw $
// Return the address of the address.
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
ACE_INLINE bool
ACE_Addr::operator == (const ACE_Addr &sap) const
{
return (sap.addr_type_ == this->addr_type_ &&
sap.addr_size_ == this->addr_size_ );
}
ACE_INLINE bool
ACE_Addr::operator != (const ACE_Addr &sap) const
{
return (sap.addr_type_ != this->addr_type_ ||
sap.addr_size_ != this->addr_size_ );
}
/// Return the size of the address.
ACE_INLINE int
ACE_Addr::get_size (void) const
{
return this->addr_size_;
}
/// Sets the size of the address.
ACE_INLINE void
ACE_Addr::set_size (int size)
{
this->addr_size_ = size;
}
/// Return the type of the address.
ACE_INLINE int
ACE_Addr::get_type (void) const
{
return this->addr_type_;
}
/// Set the type of the address.
ACE_INLINE void
ACE_Addr::set_type (int type)
{
this->addr_type_ = type;
}
ACE_INLINE unsigned long
ACE_Addr::hash (void) const
{
return 0;
}
ACE_END_VERSIONED_NAMESPACE_DECL

View File

@@ -0,0 +1,226 @@
// $Id: Arg_Shifter.cpp 91286 2010-08-05 09:04:31Z johnnyw $
#ifndef ACE_ARG_SHIFTER_T_CPP
#define ACE_ARG_SHIFTER_T_CPP
#include "ace/Arg_Shifter.h"
#include "ace/OS_NS_string.h"
#include "ace/OS_NS_strings.h"
#include "ace/OS_Errno.h"
#include "ace/OS_Memory.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
template <typename CHAR_TYPE>
ACE_Arg_Shifter_T<CHAR_TYPE>::ACE_Arg_Shifter_T (int& argc,
const CHAR_TYPE** argv,
const CHAR_TYPE** temp)
: argc_ (argc),
total_size_ (argc),
temp_ (temp),
argv_ (argv),
current_index_ (0),
back_ (argc - 1),
front_ (0)
{
this->init ();
}
template <typename CHAR_TYPE>
ACE_Arg_Shifter_T<CHAR_TYPE>::ACE_Arg_Shifter_T (int& argc,
CHAR_TYPE** argv,
CHAR_TYPE** temp)
: argc_ (argc),
total_size_ (argc),
temp_ ((const CHAR_TYPE **) temp),
argv_ ((const CHAR_TYPE **) argv),
current_index_ (0),
back_ (argc - 1),
front_ (0)
{
this->init ();
}
template <typename CHAR_TYPE>
void
ACE_Arg_Shifter_T<CHAR_TYPE>::init (void)
{
// If not provided with one, allocate a temporary array.
if (this->temp_ == 0)
ACE_NEW (this->temp_,
const CHAR_TYPE *[this->total_size_]);
if (this->temp_ != 0)
{
// Fill the temporary array.
this->argc_ = 0;
for (int i = 0; i < this->total_size_; i++)
{
this->temp_[i] = this->argv_[i];
this->argv_[i] = 0;
}
}
else
{
// Allocation failed, prohibit iteration.
this->current_index_ = this->argc_;
this->front_ = this->argc_;
}
}
template <typename CHAR_TYPE>
ACE_Arg_Shifter_T<CHAR_TYPE>::~ACE_Arg_Shifter_T (void)
{
// Delete the temporary vector.
delete [] temp_;
}
template <typename CHAR_TYPE>
const CHAR_TYPE *
ACE_Arg_Shifter_T<CHAR_TYPE>::get_current (void) const
{
const CHAR_TYPE * retval = 0;
if (this->is_anything_left ())
retval = this->temp_[current_index_];
return retval;
}
template <typename CHAR_TYPE>
const CHAR_TYPE *
ACE_Arg_Shifter_T<CHAR_TYPE>::get_the_parameter (const CHAR_TYPE *flag)
{
// the return 0's abound because this method
// would otherwise be a deep if { } else { }
// check to see if any arguments still exist
if (!this->is_anything_left())
return 0;
// check to see if the flag is the argument
int const offset = this->cur_arg_strncasecmp (flag);
if (offset == -1)
return 0;
if (offset == 0)
{
this->consume_arg ();
if (!this->is_parameter_next())
{
return 0;
}
}
// the parameter is in the middle somewhere...
return this->temp_[current_index_] + offset;
}
template <typename CHAR_TYPE>
int
ACE_Arg_Shifter_T<CHAR_TYPE>::cur_arg_strncasecmp (const CHAR_TYPE *flag)
{
// Check for a current argument
if (this->is_anything_left())
{
size_t const flag_length = ACE_OS::strlen (flag);
// Check for presence of the flag
if (ACE_OS::strncasecmp(this->temp_[current_index_],
flag,
flag_length) == 0)
{
if (ACE_OS::strlen(temp_[current_index_]) == flag_length)
{
// match and lengths are equal
return 0;
}
else
{
// matches, with more info to boot!
size_t const remaining = ACE_OS::strspn
(this->temp_[current_index_] + flag_length,
ACE_TEXT (" ")) + flag_length;
return static_cast<int> (remaining);
}
}
}
// failure
return -1;
}
template <typename CHAR_TYPE>
int
ACE_Arg_Shifter_T<CHAR_TYPE>::consume_arg (int number)
{
int retval = 0;
// Stick knowns at the end of the vector (consumed).
if (this->is_anything_left() >= number)
{
for (int i = 0, j = this->back_ - (number - 1);
i < number;
++i, ++j, ++this->current_index_)
this->argv_[j] = this->temp_[this->current_index_];
this->back_ -= number;
retval = 1;
}
return retval;
}
template <typename CHAR_TYPE>
int
ACE_Arg_Shifter_T<CHAR_TYPE>::ignore_arg (int number)
{
int retval = 0;
// Keep unknowns at the head of the vector.
if (this->is_anything_left () >= number)
{
for (int i = 0;
i < number;
i++, this->current_index_++, this->front_++)
this->argv_[this->front_] = this->temp_[this->current_index_];
retval = 1;
this->argc_ += number;
}
return retval;
}
template <typename CHAR_TYPE>
int
ACE_Arg_Shifter_T<CHAR_TYPE>::is_anything_left (void) const
{
return this->total_size_ - this->current_index_;
}
template <typename CHAR_TYPE>
int
ACE_Arg_Shifter_T<CHAR_TYPE>::is_option_next (void) const
{
return this->is_anything_left () &&
this->temp_[this->current_index_][0] == '-';
}
template <typename CHAR_TYPE>
int
ACE_Arg_Shifter_T<CHAR_TYPE>::is_parameter_next (void) const
{
return this->is_anything_left ()
&& this->temp_[this->current_index_][0] != '-';
}
template <typename CHAR_TYPE>
int
ACE_Arg_Shifter_T<CHAR_TYPE>::num_ignored_args (void) const
{
return this->front_;
}
ACE_END_VERSIONED_NAMESPACE_DECL
#endif /* ACE_ATOMIC_OP_T_CPP */

View File

@@ -0,0 +1,234 @@
// -*- C++ -*-
//=============================================================================
/**
* @file Arg_Shifter.h
*
* $Id: Arg_Shifter.h 95972 2012-07-26 10:20:42Z johnnyw $
*
* @author Seth Widoff
*/
//=============================================================================
#ifndef ACE_ARG_SHIFTER_H
#define ACE_ARG_SHIFTER_H
#include /**/ "ace/pre.h"
#include /**/ "ace/ACE_export.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "ace/Global_Macros.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
/**
* @class ACE_Arg_Shifter_T
*
* @brief This ADT operates on a specified set of arguments (@a argv).
* As known arguments are scanned, they are shifted to the back of the
* @a argv vector, so deeper levels of argument parsing can locate the yet
* unprocessed arguments at the beginning of the vector.
*
* Nomenclature:
* argument - a member of the argv array
* option - an argument starting with '-'
* flag - synonym for "option"
* parameter value - an argument not starting with '-'
* parameter - synonym for "parameter value"
*
* The @c ACE_Arg_Shifter copies the pointers of the @a argv vector
* into a temporary array, emptying the original. As the @c ACE_Arg_Shifter
* iterates over the temporary array, it places known arguments in the rear
* of the original array and places the unknown ones in the beginning of the
* original array. It modifies argc to be the number of unknown arguments,
* so it looks to the caller as if the original array contains only unknown
* arguments. So, after @c ACE_Arg_Shifter has visited all the arguments
* in the temporary array, the original @a argv array appears to contain
* only the unknown arguments in their original order (but it actually has
* all the known arguments, too, beyond argc).
*/
template <typename CHAR_TYPE>
class ACE_Arg_Shifter_T
{
public:
// = Initialization and termination methods.
/**
* Initialize the ACE_Arg_Shifter to the vector over which to
* iterate. Optionally, also provide the temporary array for
* use in shifting the arguments. If ACE_Arg_Shifter must allocate
* the temporary vector internally and dynamic allocation fails, the
* ACE_Arg_Shifter will set all indicators to end of the vector,
* forbidding iteration. Following iteration over @a argv, the
* @a argc value will be updated to contain the number of
* unconsumed arguments.
* @param argc The number of strings in @a argv. @a argc will be
* updated to reflect the number of unconsumed arguments.
* @param argv The argument vector to shift. The string pointers in
* the vector will be reordered to place the @a argc unconsumed
* arguments at the front of the vector.
* @param temp A vector of @c CHAR_TYPE pointers at least @a argc
* elements long. The vector will be used for argument shifting as
* the specified @a argv vector is consumed. The vector must not
* be modified while this object exists. If this argument is 0
* (the default) the object will allocate and free the temporary
* vector transparently.
*/
ACE_Arg_Shifter_T (int& argc,
const CHAR_TYPE **argv,
const CHAR_TYPE **temp = 0);
/// Same behavior as the preceding constructor, but without the
/// "const" qualifier.
ACE_Arg_Shifter_T (int& argc,
CHAR_TYPE **argv,
CHAR_TYPE **temp = 0);
/// Destructor.
~ACE_Arg_Shifter_T (void);
/// Get the current head of the vector.
const CHAR_TYPE *get_current (void) const;
/**
* If the @a flag matches the current_arg of arg shifter
* this method will attempt to return the associated
* parameter value
*
* Safe to call without checking that a current arg exists
*
* In the following examples, a pointer to the char* "value" is ret
*
* eg: main -foobar value, main -FooBar value
* main -FOOBARvalue
*
* all of the above will all match the @a flag == -FooBar
* and will return a char* to "value"
*
* main -foobar 4 would succeed and return a char* to "4"
* main -foobar -4 does not succeed (-4 is not a parameter)
* but instead, would return 0
*
* 0 is returned:
* If the current argument does not match flag
* If there is no parameter found after a 'matched' flag
*
* If the flag is matched and the flag and parameter DO NOT RUN
* together, the flag is consumed, the parameter is returned,
* and the new current argument is the parameter value.
* ie '-foobarflag VALUE' leaves the new cur arg == "VALUE"
*
* If the flag is matched and the flag and parameter RUN
* together '-foobarflagVALUE', the flag is NOT consumed
* and the cur arg is left pointing to the entire flag/value pair
*/
const CHAR_TYPE *get_the_parameter (const CHAR_TYPE* flag);
/**
* Check if the current argument matches (case insensitive) @a flag
*
* ------------------------------------------------------------
*
* Case A: Perfect Match (case insensitive)
* 0 is returned.
*
* ie: when current_arg = "-foobar" or "-FOOBAR" or "-fooBAR"
* this->cur_arg_strncasecmp ("-FooBar);
* will return 0
*
* ------------------------------------------------------------
*
* Case B: Perfect Match (case insensitive) but the current_arg
* is longer than the flag. Returns a number equal to the index
* in the char* indicating the start of the extra characters
*
* ie: when current_arg = "-foobar98023"
* this->cur_arg_strncasecmp ("-FooBar);
* will return 7
*
* Notice: this number will always be > 0
*
* ------------------------------------------------------------
*
* Case C: If neither of Case A or B is met (no match)
* then -1 is returned
*/
int cur_arg_strncasecmp (const CHAR_TYPE *flag);
/// Consume @a number argument(s) by sticking them/it on the end of
/// the vector.
int consume_arg (int number = 1);
/// Place @a number arguments in the same relative order ahead of the
/// known arguments in the vector.
int ignore_arg (int number = 1);
/// Returns the number of args left to see in the vector.
int is_anything_left (void) const;
/// Returns 1 if there's a next item in the vector and it begins with
/// '-'.
int is_option_next (void) const;
/// Returns 1 if there's a next item in the vector and it doesn't
/// begin with '-'.
int is_parameter_next (void) const;
/// Returns the number of irrelevant args seen.
int num_ignored_args (void) const;
private:
/// Copy Constructor should not be used.
ACE_UNIMPLEMENTED_FUNC (ACE_Arg_Shifter_T (const ACE_Arg_Shifter_T<CHAR_TYPE>&))
/// Assignment '=' operator should not be used.
ACE_UNIMPLEMENTED_FUNC (ACE_Arg_Shifter_T operator= (const ACE_Arg_Shifter_T<CHAR_TYPE>&))
/// Refactor the constructor logic.
void init (void);
/// The size of the argument vector.
int& argc_;
/// The size of argv_.
int total_size_;
/// The temporary array over which we traverse.
const CHAR_TYPE **temp_;
/// The array in which the arguments are reordered.
const CHAR_TYPE **argv_;
/// The element in <temp_> we're currently examining.
int current_index_;
/// The index of <argv_> in which we'll stick the next unknown
/// argument.
int back_;
/// The index of <argv_> in which we'll stick the next known
/// argument.
/** This is not really the "front" at all. It's the point after
* which the unknown arguments end and at which the known arguments begin.
*/
int front_;
};
typedef ACE_Arg_Shifter_T<ACE_TCHAR> ACE_Arg_Shifter;
ACE_END_VERSIONED_NAMESPACE_DECL
#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
#include "ace/Arg_Shifter.cpp"
#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
#pragma implementation ("Arg_Shifter.cpp")
#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
#include /**/ "ace/post.h"
#endif /* ACE_ARG_SHIFTER_H */

View File

@@ -0,0 +1,190 @@
#include "ace/Argv_Type_Converter.h"
#if !defined (__ACE_INLINE__)
#include "ace/Argv_Type_Converter.inl"
#endif /* __ACE_INLINE__ */
#include "ace/OS_NS_string.h"
#include "ace/OS_Errno.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
#if defined (ACE_USES_WCHAR)
ACE_Argv_Type_Converter::ACE_Argv_Type_Converter (int &argc, wchar_t** argv)
: saved_argc_ (argc),
char_argv_ (0),
wchar_argv_ (argv),
before_pass_argc_ (argc),
original_type_ (true),
wchar_passed_ (false),
char_passed_ (false)
{
this->initialize ();
for (int i = 0; i < argc; ++i)
this->char_argv_[i] = ACE_OS::strdup (ACE_TEXT_ALWAYS_CHAR (argv[i]));
}
#endif // ACE_USES_WCHAR
ACE_Argv_Type_Converter::ACE_Argv_Type_Converter (int &argc, char **argv)
: saved_argc_(argc),
char_argv_(argv)
#if defined (ACE_USES_WCHAR)
, wchar_argv_(0),
before_pass_argc_(argc),
original_type_(false),
wchar_passed_(false),
char_passed_(false)
{
this->initialize();
for (int i = 0; i < argc; ++i)
this->wchar_argv_[i] = ACE_OS::strdup (ACE_TEXT_ANTI_TO_TCHAR (argv[i]));
}
#else
{
}
#endif // ACE_USES_WCHAR
ACE_Argv_Type_Converter::~ACE_Argv_Type_Converter (void)
{
#if defined (ACE_USES_WCHAR)
// selectively delete the 'copy' of argv
if (this->original_type_)
{
// if original type is wchar_t
if (this->char_passed_)
this->align_wchar_with_char ();
for (int i = 0; i < this->before_pass_argc_; ++i)
ACE_OS::free (this->char_argv_[i]);
delete [] this->char_argv_;
}
else
{
// if original type is char
if (this->wchar_passed_)
this->align_char_with_wchar ();
for (int i = 0; i < this->before_pass_argc_; ++i)
ACE_OS::free (this->wchar_argv_[i]);
delete [] this->wchar_argv_;
}
#endif // ACE_USES_WCHAR
}
#if defined (ACE_USES_WCHAR)
void
ACE_Argv_Type_Converter::initialize (void)
{
if (this->original_type_)
{
// Make a copy of argv in 'char'. type Create one more argv entry
// than original argc for the NULL.
ACE_NEW (char_argv_,
char *[this->saved_argc_ + 1]);
this->char_argv_[saved_argc_] = 0; // last entry of argv is
// always a NULL
}
else
{
// make a copy of argv in 'wchar_t' type
ACE_NEW (this->wchar_argv_,
wchar_t*[this->saved_argc_ + 1]);
this->wchar_argv_[saved_argc_] = 0;
}
}
void
ACE_Argv_Type_Converter::align_char_with_wchar (void)
{
for (int wchar_argv_index = 0; wchar_argv_index < this->saved_argc_;
++wchar_argv_index)
{
wchar_t *match_argv = this->wchar_argv_[wchar_argv_index];
// if n'th entries of both argv lists are different
if (ACE_OS::strcmp (this->char_argv_[wchar_argv_index],
ACE_TEXT_ALWAYS_CHAR (match_argv)) != 0)
{
// loop through the wchar argv list entries that are after
// wchar_argv_index
for (int i = wchar_argv_index + 1; i < before_pass_argc_; ++i)
{
if (ACE_OS::strcmp (this->char_argv_[i],
ACE_TEXT_ALWAYS_CHAR (match_argv)) == 0)
{
// swap the pointers in the char argv list
char *temp = this->char_argv_[wchar_argv_index];
this->char_argv_[wchar_argv_index] = this->char_argv_[i];
this->char_argv_[i] = temp;
break;
}
}
}
}
this->cleanup ();
}
void
ACE_Argv_Type_Converter::align_wchar_with_char (void)
{
for (int char_argv_index = 0; char_argv_index < saved_argc_;
++char_argv_index)
{
char* match_argv = this->char_argv_[char_argv_index];
// if n'th entries of both argv lists are different
if (ACE_OS::strcmp (
ACE_TEXT_ALWAYS_CHAR (this->wchar_argv_[char_argv_index]),
match_argv) != 0)
{
// loop through the wchar argv list entries that are after
// wchar_argv_index
for (int i = char_argv_index + 1; i < this->before_pass_argc_; ++i)
{
if (ACE_OS::strcmp (
ACE_TEXT_ALWAYS_CHAR(this->wchar_argv_[i]),
match_argv) == 0) {
// swap the pointers in the char argv list
wchar_t* temp = this->wchar_argv_[char_argv_index];
this->wchar_argv_[char_argv_index] = this->wchar_argv_[i];
this->wchar_argv_[i] = temp;
break;
}
}
}
}
this->cleanup();
}
void
ACE_Argv_Type_Converter::cleanup (void)
{
for (int i = this->saved_argc_; i < this->before_pass_argc_; ++i)
{
// Check whether it's ours to delete.
if (original_type_)
{
ACE_OS::free (this->char_argv_[i]);
this->char_argv_[i] = 0;
}
else
{
ACE_OS::free (this->wchar_argv_[i]);
this->wchar_argv_[i] = 0;
}
}
this->before_pass_argc_ = this->saved_argc_;
this->wchar_passed_ = false;
this->char_passed_ = false;
}
#endif // ACE_USES_WCHAR
ACE_END_VERSIONED_NAMESPACE_DECL

View File

@@ -0,0 +1,117 @@
// -*- C++ -*-
//=============================================================================
/**
* @file Argv_Type_Converter.h
*
* @author Si Mong Park <spark@ociweb.com>
*/
//=============================================================================
#ifndef ACE_ARGV_TYPE_CONVERTER_H
#define ACE_ARGV_TYPE_CONVERTER_H
#include /**/ "ace/pre.h"
#include /**/ "ace/ACE_export.h"
#include "ace/OS_Memory.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
/**
* @class ACE_Argv_Type_Converter
*
* @brief To convert 'char' input/command line parameter to 'wchar_t'.
*
* This class is to convert 'char' type command line parameter to
* wide-character (wchar_t) format and stores the copy of it.
* This is useful for all classes that use 'char**' argv but cannot
* be converted into 'ACE_TCHAR**' version.
* Note that the converted data will be lost upon destruction, so
* classes should use this class as their data member.
*/
class ACE_Export ACE_Argv_Type_Converter
{
public:
ACE_Argv_Type_Converter (int &argc, char** argv);
#if defined (ACE_USES_WCHAR)
ACE_Argv_Type_Converter (int &argc, wchar_t** argv);
#endif // ACE_USES_WCHAR
~ACE_Argv_Type_Converter (void);
/// Returns the pointer of converted command line.
ACE_TCHAR** get_TCHAR_argv (void);
/// Returns the pointer of ASCII (char) command line.
char** get_ASCII_argv (void);
/// Returns the number of sub parameters (argc).
int& get_argc (void);
private:
/// Copy Constructor should not be used.
ACE_Argv_Type_Converter (const ACE_Argv_Type_Converter&);
/// Assignment '=' operator should not be used.
ACE_Argv_Type_Converter operator= (const ACE_Argv_Type_Converter&);
#if defined (ACE_USES_WCHAR)
/// Perform common initialization for two Ctor's.
void initialize (void);
/// Align all entries in the char type argv list with wchar_t type
/// argv list.
void align_char_with_wchar (void);
/// Align all entries in the wchar_t type argv list with char type
/// argv list.
void align_wchar_with_char (void);
/// Clean up removed (consumed) argv entries and reset the pass flags.
void cleanup (void);
#endif // ACE_USES_WCHAR
private:
/// Original number of input parameter, same as 'argc'.
int &saved_argc_;
/// Data member pointer that contains converted argv in ACE_ANTI_TCHAR.
char** char_argv_;
#if defined (ACE_USES_WCHAR)
/// Data member pointer that contains converted argv in ACE_TCHAR.
wchar_t** wchar_argv_;
/// argc value before any argv has been passed.
int before_pass_argc_;
/// false represents original argv passed in is char, and true
/// represents wchar_t.
bool const original_type_;
/// true indicates wchar_t type argv has been passed.
bool wchar_passed_;
/// true indicates char type argv has been passed.
bool char_passed_;
#endif /* ACE_USES_WCHAR */
};
ACE_END_VERSIONED_NAMESPACE_DECL
#if defined (__ACE_INLINE__)
#include "ace/Argv_Type_Converter.inl"
#endif /* __ACE_INLINE__ */
#include /**/ "ace/post.h"
#endif /* ACE_ARGV_TYPE_CONVERTER_H */

View File

@@ -0,0 +1,41 @@
// -*- C++ -*-
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
ACE_INLINE ACE_TCHAR**
ACE_Argv_Type_Converter::get_TCHAR_argv (void)
{
#if defined (ACE_USES_WCHAR)
if (this->char_passed_)
{
this->align_wchar_with_char ();
}
this->wchar_passed_ = true;
return this->wchar_argv_;
#else
return this->char_argv_;
#endif // ACE_USES_WCHAR
}
ACE_INLINE char**
ACE_Argv_Type_Converter::get_ASCII_argv (void)
{
#if defined (ACE_USES_WCHAR)
if (this->wchar_passed_)
{
this->align_char_with_wchar ();
}
this->char_passed_ = true;
#endif // ACE_USES_WCHAR
return this->char_argv_;
}
ACE_INLINE int&
ACE_Argv_Type_Converter::get_argc (void)
{
return this->saved_argc_;
}
ACE_END_VERSIONED_NAMESPACE_DECL

View File

@@ -0,0 +1,233 @@
#ifndef ACE_ARRAY_BASE_CPP
#define ACE_ARRAY_BASE_CPP
#include "ace/Array_Base.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#if !defined (__ACE_INLINE__)
#include "ace/Array_Base.inl"
#endif /* __ACE_INLINE__ */
#include "ace/Malloc_Base.h"
#include "ace/os_include/os_errno.h"
#include <algorithm>
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
// Dynamically initialize an array.
template <class T>
ACE_Array_Base<T>::ACE_Array_Base (typename ACE_Array_Base<T>::size_type size,
ACE_Allocator *alloc)
: max_size_ (size),
cur_size_ (size),
allocator_ (alloc)
{
if (this->allocator_ == 0)
this->allocator_ = ACE_Allocator::instance ();
if (size != 0)
{
ACE_ALLOCATOR (this->array_,
(T *) this->allocator_->malloc (size * sizeof (T)));
for (size_type i = 0; i < size; ++i)
new (&array_[i]) T;
}
else
this->array_ = 0;
}
template <class T>
ACE_Array_Base<T>::ACE_Array_Base (typename ACE_Array_Base<T>::size_type size,
const T &default_value,
ACE_Allocator *alloc)
: max_size_ (size),
cur_size_ (size),
allocator_ (alloc)
{
if (this->allocator_ == 0)
this->allocator_ = ACE_Allocator::instance ();
if (size != 0)
{
ACE_ALLOCATOR (this->array_,
(T *) this->allocator_->malloc (size * sizeof (T)));
for (size_type i = 0; i < size; ++i)
new (&array_[i]) T (default_value);
}
else
this->array_ = 0;
}
// The copy constructor (performs initialization).
template <class T>
ACE_Array_Base<T>::ACE_Array_Base (const ACE_Array_Base<T> &s)
: max_size_ (s.size ()),
cur_size_ (s.size ()),
allocator_ (s.allocator_)
{
if (this->allocator_ == 0)
this->allocator_ = ACE_Allocator::instance ();
ACE_ALLOCATOR (this->array_,
(T *) this->allocator_->malloc (s.size () * sizeof (T)));
for (size_type i = 0; i < this->size (); ++i)
new (&this->array_[i]) T (s.array_[i]);
}
// Assignment operator (performs assignment).
template <class T> void
ACE_Array_Base<T>::operator= (const ACE_Array_Base<T> &s)
{
// Check for "self-assignment".
if (this != &s)
{
if (this->max_size_ < s.size ())
{
// Need to reallocate memory.
// Strongly exception-safe assignment.
//
// Note that we're swapping the allocators here, too.
// Should we? Probably. "*this" should be a duplicate of
// the "right hand side".
ACE_Array_Base<T> tmp (s);
this->swap (tmp);
}
else
{
// Underlying array is large enough. No need to reallocate
// memory.
//
// "*this" still owns the memory for the underlying array.
// Do not swap out the allocator.
//
// @@ Why don't we just drop the explicit destructor and
// placement operator new() calls with a straight
// element-by-element assignment? Is the existing
// approach more efficient?
// -Ossama
ACE_DES_ARRAY_NOFREE (this->array_,
s.size (),
T);
this->cur_size_ = s.size ();
for (size_type i = 0; i < this->size (); ++i)
new (&this->array_[i]) T (s.array_[i]);
}
}
}
// Set an item in the array at location slot.
template <class T> int
ACE_Array_Base<T>::set (const T &new_item,
typename ACE_Array_Base<T>::size_type slot)
{
if (this->in_range (slot))
{
this->array_[slot] = new_item;
return 0;
}
else
return -1;
}
// Get an item in the array at location slot.
template <class T> int
ACE_Array_Base<T>::get (T &item,
typename ACE_Array_Base<T>::size_type slot) const
{
if (this->in_range (slot))
{
// Copies the item. If you don't want to copy, use operator []
// instead (but then you'll be responsible for range checking).
item = this->array_[slot];
return 0;
}
else
return -1;
}
template<class T> int
ACE_Array_Base<T>::max_size (typename ACE_Array_Base<T>::size_type new_size)
{
if (new_size > this->max_size_)
{
T *tmp = 0;
ACE_ALLOCATOR_RETURN (tmp,
(T *) this->allocator_->malloc (new_size * sizeof (T)),
-1);
for (size_type i = 0; i < this->cur_size_; ++i)
new (&tmp[i]) T (this->array_[i]);
// Initialize the new portion of the array that exceeds the
// previously allocated section.
for (size_type j = this->cur_size_; j < new_size; ++j)
new (&tmp[j]) T;
ACE_DES_ARRAY_FREE (this->array_,
this->max_size_,
this->allocator_->free,
T);
this->array_ = tmp;
this->max_size_ = new_size;
this->cur_size_ = new_size;
}
return 0;
}
template<class T> int
ACE_Array_Base<T>::size (typename ACE_Array_Base<T>::size_type new_size)
{
int const r = this->max_size (new_size);
if (r == 0)
this->cur_size_ = new_size;
return r;
}
template<class T>
void
ACE_Array_Base<T>::swap (ACE_Array_Base<T> & rhs)
{
std::swap (this->max_size_ , rhs.max_size_);
std::swap (this->cur_size_ , rhs.cur_size_);
std::swap (this->array_ , rhs.array_);
std::swap (this->allocator_, rhs.allocator_);
}
// ****************************************************************
template <class T> int
ACE_Array_Iterator<T>::next (T *&item)
{
// ACE_TRACE ("ACE_Array_Iterator<T>::next");
if (this->done ())
{
item = 0;
return 0;
}
else
{
item = &array_[current_];
return 1;
}
}
ACE_END_VERSIONED_NAMESPACE_DECL
#endif /* ACE_ARRAY_BASE_CPP */

View File

@@ -0,0 +1,254 @@
// -*- C++ -*-
//=============================================================================
/**
* @file Array_Base.h
*
* @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
*/
//=============================================================================
#ifndef ACE_ARRAY_BASE_H
#define ACE_ARRAY_BASE_H
#include /**/ "ace/pre.h"
#include /**/ "ace/config-all.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "ace/Global_Macros.h"
#include "ace/Malloc_Base.h"
#include <iterator> /* For reverse_iterator adapters */
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
// Forward declaration.
template <class T> class ACE_Array_Iterator;
/**
* @class ACE_Array_Base
*
* @brief Implement a simple dynamic array
*
* This parametric class implements a simple dynamic array;
* resizing must be controlled by the user. No comparison or find
* operations are implemented.
*/
template<class T>
class ACE_Array_Base
{
public:
// Old/ACE-style traits.
typedef T TYPE;
typedef ACE_Array_Iterator<T> ITERATOR;
// STL-style typedefs/traits.
typedef T value_type;
typedef value_type * iterator;
typedef value_type const * const_iterator;
typedef value_type & reference;
typedef value_type const & const_reference;
typedef value_type * pointer;
typedef value_type const * const_pointer;
typedef ptrdiff_t difference_type;
typedef ACE_Allocator::size_type size_type;
ACE_DECLARE_STL_REVERSE_ITERATORS
// = Initialization and termination methods.
/// Dynamically create an uninitialized array.
ACE_Array_Base (size_type size = 0,
ACE_Allocator * the_allocator = 0);
/// Dynamically initialize the entire array to the @a default_value.
ACE_Array_Base (size_type size,
T const & default_value,
ACE_Allocator * the_allocator = 0);
/**
* The copy constructor performs initialization by making an exact
* copy of the contents of parameter @a s, i.e., *this == s will
* return true.
*/
ACE_Array_Base (ACE_Array_Base<T> const & s);
/**
* Assignment operator performs an assignment by making an exact
* copy of the contents of parameter @a s, i.e., *this == s will
* return true. Note that if the <max_size_> of <array_> is >= than
* <s.max_size_> we can copy it without reallocating. However, if
* <max_size_> is < <s.max_size_> we must delete the <array_>,
* reallocate a new <array_>, and then copy the contents of <s>.
*/
void operator= (ACE_Array_Base<T> const & s);
/// Clean up the array (e.g., delete dynamically allocated memory).
~ACE_Array_Base (void);
// = Set/get methods.
/// Set item in the array at location @a slot. Doesn't
/// perform range checking.
T & operator[] (size_type slot);
/// Get item in the array at location @a slot. Doesn't
/// perform range checking.
T const & operator[] (size_type slot) const;
/// Set an item in the array at location @a slot. Returns
/// -1 if @a slot is not in range, else returns 0.
int set (T const & new_item, size_type slot);
/**
* Get an item in the array at location @a slot. Returns -1 if
* @a slot is not in range, else returns 0. Note that this function
* copies the item. If you want to avoid the copy, you can use
* the const operator [], but then you'll be responsible for range checking.
*/
int get (T & item, size_type slot) const;
/// Returns the <cur_size_> of the array.
size_type size (void) const;
/**
* Changes the size of the array to match @a new_size.
* It copies the old contents into the new array.
* Return -1 on failure.
*/
int size (size_type new_size);
/// Returns the <max_size_> of the array.
size_type max_size (void) const;
/**
* Changes the size of the array to match @a new_size.
* It copies the old contents into the new array.
* Return -1 on failure.
* It does not affect new_size
*/
int max_size (size_type new_size);
/**
* @name Forward Iterator Accessors
*
* Forward iterator accessors.
*/
//@{
iterator begin (void);
iterator end (void);
const_iterator begin (void) const;
const_iterator end (void) const;
//@}
/**
* @name Reverse Iterator Accessors
*
* Reverse iterator accessors.
*/
//@{
reverse_iterator rbegin (void);
reverse_iterator rend (void);
const_reverse_iterator rbegin (void) const;
const_reverse_iterator rend (void) const;
//@}
/// Swap the contents of this array with the given @a array in
/// an exception-safe manner.
void swap (ACE_Array_Base<T> & array);
protected:
/// Returns 1 if @a slot is within range, i.e., 0 >= @a slot <
/// @c cur_size_, else returns 0.
bool in_range (size_type slot) const;
/// Maximum size of the array, i.e., the total number of @c T elements
/// in @c array_.
size_type max_size_;
/**
* Current size of the array. This starts out being == to
* <max_size_>. However, if we are assigned a smaller array, then
* <cur_size_> will become less than <max_size_>. The purpose of
* keeping track of both sizes is to avoid reallocating memory if we
* don't have to.
*/
size_type cur_size_;
/// Pointer to the array's storage buffer.
value_type * array_;
/// Allocation strategy of the ACE_Array_Base.
ACE_Allocator * allocator_;
friend class ACE_Array_Iterator<T>;
};
// ****************************************************************
/**
* @class ACE_Array_Iterator
*
* @brief Implement an iterator over an ACE_Array.
*
* This iterator is safe in the face of array element deletions.
* But it is NOT safe if the array is resized (via the ACE_Array
* assignment operator) during iteration. That would be very
* odd, and dangerous.
*/
template <class T>
class ACE_Array_Iterator
{
public:
// = Initialization method.
ACE_Array_Iterator (ACE_Array_Base<T> &);
// = Iteration methods.
/// Pass back the @a next_item that hasn't been seen in the Array.
/// Returns 0 when all items have been seen, else 1.
int next (T *&next_item);
/// Move forward by one element in the Array. Returns 0 when all the
/// items in the Array have been seen, else 1.
int advance (void);
/// Returns 1 when all items have been seen, else 0.
int done (void) const;
/// Dump the state of an object.
void dump (void) const;
/// Declare the dynamic allocation hooks.
ACE_ALLOC_HOOK_DECLARE;
private:
/// Pointer to the current item in the iteration.
size_t current_;
/// Pointer to the Array we're iterating over.
ACE_Array_Base<T> &array_;
};
ACE_END_VERSIONED_NAMESPACE_DECL
#if defined (__ACE_INLINE__)
#include "ace/Array_Base.inl"
#endif /* __ACE_INLINE__ */
#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
#include "ace/Array_Base.cpp"
#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
#pragma implementation ("Array_Base.cpp")
#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
#include /**/ "ace/post.h"
#endif /* ACE_ARRAY_BASE_H */

View File

@@ -0,0 +1,143 @@
// -*- C++ -*-
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
// Clean up the array (e.g., delete dynamically allocated memory).
template <class T> ACE_INLINE
ACE_Array_Base<T>::~ACE_Array_Base (void)
{
ACE_DES_ARRAY_FREE (this->array_,
this->max_size_,
this->allocator_->free,
T);
}
template <class T>
ACE_INLINE typename ACE_Array_Base<T>::iterator
ACE_Array_Base<T>::begin (void)
{
return this->array_;
}
template <class T>
ACE_INLINE typename ACE_Array_Base<T>::iterator
ACE_Array_Base<T>::end (void)
{
return this->array_ + this->cur_size_;
}
template <class T>
ACE_INLINE typename ACE_Array_Base<T>::const_iterator
ACE_Array_Base<T>::begin (void) const
{
return this->array_;
}
template <class T>
ACE_INLINE typename ACE_Array_Base<T>::const_iterator
ACE_Array_Base<T>::end (void) const
{
return this->array_ + this->cur_size_;
}
template <class T>
ACE_INLINE typename ACE_Array_Base<T>::reverse_iterator
ACE_Array_Base<T>::rbegin (void)
{
return reverse_iterator (this->end ());
}
template <class T>
ACE_INLINE typename ACE_Array_Base<T>::reverse_iterator
ACE_Array_Base<T>::rend (void)
{
return reverse_iterator (this->begin ());
}
template <class T>
ACE_INLINE typename ACE_Array_Base<T>::const_reverse_iterator
ACE_Array_Base<T>::rbegin (void) const
{
return const_reverse_iterator (this->end ());
}
template <class T>
ACE_INLINE typename ACE_Array_Base<T>::const_reverse_iterator
ACE_Array_Base<T>::rend (void) const
{
return const_reverse_iterator (this->begin ());
}
template <class T> ACE_INLINE typename ACE_Array_Base<T>::size_type
ACE_Array_Base<T>::size (void) const
{
return this->cur_size_;
}
template <class T> ACE_INLINE typename ACE_Array_Base<T>::size_type
ACE_Array_Base<T>::max_size (void) const
{
return this->max_size_;
}
template <class T> ACE_INLINE bool
ACE_Array_Base<T>::in_range (typename ACE_Array_Base<T>::size_type index) const
{
return index < this->cur_size_;
}
template <class T> ACE_INLINE T &
ACE_Array_Base<T>::operator[] (typename ACE_Array_Base<T>::size_type index)
{
return this->array_[index];
}
template <class T> ACE_INLINE const T &
ACE_Array_Base<T>::operator[] (typename ACE_Array_Base<T>::size_type index) const
{
return this->array_[index];
}
// ****************************************************************
template <class T> ACE_INLINE void
ACE_Array_Iterator<T>::dump (void) const
{
#if defined (ACE_HAS_DUMP)
// ACE_TRACE ("ACE_Array_Iterator<T>::dump");
#endif /* ACE_HAS_DUMP */
}
template <class T> ACE_INLINE
ACE_Array_Iterator<T>::ACE_Array_Iterator (ACE_Array_Base<T> &a)
: current_ (0),
array_ (a)
{
// ACE_TRACE ("ACE_Array_Iterator<T>::ACE_Array_Iterator");
}
template <class T> ACE_INLINE int
ACE_Array_Iterator<T>::advance (void)
{
// ACE_TRACE ("ACE_Array_Iterator<T>::advance");
if (this->current_ < array_.size ())
{
++this->current_;
return 1;
}
else
{
// Already finished iterating.
return 0;
}
}
template <class T> ACE_INLINE int
ACE_Array_Iterator<T>::done (void) const
{
ACE_TRACE ("ACE_Array_Iterator<T>::done");
return this->current_ >= array_.size ();
}
ACE_END_VERSIONED_NAMESPACE_DECL

View File

@@ -0,0 +1,260 @@
#ifndef ACE_ARRAY_MAP_CPP
#define ACE_ARRAY_MAP_CPP
#include "ace/Array_Map.h"
#ifndef __ACE_INLINE__
# include "ace/Array_Map.inl"
#endif /* !__ACE_INLINE__ */
#include "ace/checked_iterator.h"
#include <algorithm>
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
template<typename Key, typename Value, class EqualTo>
template<typename InputIterator>
ACE_Array_Map<Key, Value, EqualTo>::ACE_Array_Map (InputIterator f,
InputIterator l)
: size_ (l - f)
, capacity_ (size_)
, nodes_ (size_ == 0 ? 0 : new value_type[size_])
{
(void) std::copy (f,
l,
ACE_make_checked_array_iterator (this->begin (),
this->size_));
// iterator n = this->begin ();
// for (InputIterator i = f; i != l; ++i, ++n)
// *n = *i;
}
template<typename Key, typename Value, class EqualTo>
ACE_Array_Map<Key, Value, EqualTo>::ACE_Array_Map (
ACE_Array_Map<Key, Value, EqualTo> const & map)
: size_ (map.size_)
, capacity_ (map.size_)
, nodes_ (size_ == 0 ? 0 : new value_type[size_])
{
std::copy (map.begin (),
map.end (),
ACE_make_checked_array_iterator (this->begin (),
this->size_));
// iterator f = map.begin ();
// iterator l = map.end ();
// iterator n = this->begin ();
// for (iterator i = f; i != l; ++i, ++n)
// *n = *i;
}
template<typename Key, typename Value, class EqualTo>
ACE_Array_Map<Key, Value, EqualTo>::~ACE_Array_Map (void)
{
delete[] this->nodes_;
}
template<typename Key, typename Value, class EqualTo>
void
ACE_Array_Map<Key, Value, EqualTo>::swap (
ACE_Array_Map<Key, Value, EqualTo> & map)
{
std::swap (this->size_, map.size_);
std::swap (this->capacity_, map.capacity_);
std::swap (this->nodes_, map.nodes_);
}
template<typename Key, typename Value, class EqualTo>
std::pair<typename ACE_Array_Map<Key, Value, EqualTo>::iterator, bool>
ACE_Array_Map<Key, Value, EqualTo>::insert (
typename ACE_Array_Map<Key, Value, EqualTo>::value_type const & x)
{
// Linear insertion due to linear duplicate key search.
bool inserted = false;
iterator i = this->find (x.first);
if (i == this->end ())
{
// Add the element to the array.
size_type const old_size = this->size ();
this->grow (1); // Increase size by at least one.
i = this->begin () + old_size;
*i = x;
++this->size_;
inserted = true;
}
return std::make_pair (i, inserted);
}
template<typename Key, typename Value, class EqualTo>
template<typename InputIterator>
void
ACE_Array_Map<Key, Value, EqualTo>::insert (InputIterator f, InputIterator l)
{
this->grow (l - f); // Preallocate storage.
for (InputIterator i = f; i != l; ++i)
{
(void) this->insert (*i);
}
}
template<typename Key, typename Value, class EqualTo>
void
ACE_Array_Map<Key, Value, EqualTo>::erase (
typename ACE_Array_Map<Key, Value, EqualTo>::iterator pos)
{
iterator const first = this->begin ();
iterator const last = this->end ();
if (pos >= first && pos < last)
{
if (pos != last - 1)
{
// Relocate the tail element to the location of the erased
// element to prevent introduction of "holes" in the
// underlying array.
*pos = *(last - 1);
}
// Explicitly destroy the tail element by assigning a default
// constructed instance to it. Note that this also works for
// the case of a map of size 1.
*(last - 1) = value_type ();
--this->size_;
}
}
template<typename Key, typename Value, class EqualTo>
typename ACE_Array_Map<Key, Value, EqualTo>::size_type
ACE_Array_Map<Key, Value, EqualTo>::erase (
typename ACE_Array_Map<Key, Value, EqualTo>::key_type const & k)
{
iterator pos = this->find (k);
size_type const old_size = this->size_;
this->erase (pos);
return old_size - this->size_;
}
template<typename Key, typename Value, class EqualTo>
void
ACE_Array_Map<Key, Value, EqualTo>::erase (
typename ACE_Array_Map<Key, Value, EqualTo>::iterator first,
typename ACE_Array_Map<Key, Value, EqualTo>::iterator last)
{
if (this->begin () <= first && first < last && last < this->end ())
for (iterator i = first; i != last; ++i)
this->erase (i);
}
template<typename Key, typename Value, class EqualTo>
void
ACE_Array_Map<Key, Value, EqualTo>::clear (void)
{
this->size_ = 0; // No need to deallocate array nor destroy elements.
}
template<typename Key, typename Value, class EqualTo>
typename ACE_Array_Map<Key, Value, EqualTo>::iterator
ACE_Array_Map<Key, Value, EqualTo>::find (
typename ACE_Array_Map<Key, Value, EqualTo>::key_type const & k)
{
iterator const the_end = this->end ();
EqualTo eq;
for (iterator i = this->begin (); i != the_end; ++i)
if (eq (k, i->first))
return i;
return this->end ();
}
template<typename Key, typename Value, class EqualTo>
typename ACE_Array_Map<Key, Value, EqualTo>::const_iterator
ACE_Array_Map<Key, Value, EqualTo>::find (
typename ACE_Array_Map<Key, Value, EqualTo>::key_type const & k) const
{
const_iterator const the_end = this->end ();
EqualTo eq;
for (const_iterator i = this->begin (); i != the_end; ++i)
if (eq (k, i->first))
return i;
return this->end ();
}
template<typename Key, typename Value, class EqualTo>
void
ACE_Array_Map<Key, Value, EqualTo>::grow (
typename ACE_Array_Map<Key, Value, EqualTo>::size_type s)
{
if (this->size () + s > this->capacity_)
{
// This implementation focuses more on static footprint than
// speed.
// Strongly exception safe.
ACE_Array_Map<Key, Value, EqualTo> temp (this->size () + s);
std::copy (this->begin (),
this->end (),
ACE_make_checked_array_iterator (temp.begin (),
temp.capacity_));
size_type const n = this->size (); // Do not swap out the size
// since we bypassed the
// temporary map's element
// counting code.
this->swap (temp);
this->size_ = n;
}
}
// ---------------------------------------------------------------
template <typename Key, typename Value, class EqualTo>
bool
operator== (ACE_Array_Map<Key, Value, EqualTo> const & lhs,
ACE_Array_Map<Key, Value, EqualTo> const & rhs)
{
// Do not include Array_Map capacity in comparison. It isn't useful
// in this case.
return (lhs.size () == rhs.size ()
&& std::equal (lhs.begin (),
lhs.end (),
ACE_make_checked_array_iterator (rhs.begin (),
rhs.size ())));
}
template <typename Key, typename Value, class EqualTo>
bool
operator< (ACE_Array_Map<Key, Value, EqualTo> const & lhs,
ACE_Array_Map<Key, Value, EqualTo> const & rhs)
{
return std::lexicographical_compare (lhs.begin (), lhs.end (),
rhs.begin (), rhs.end ());
}
ACE_END_VERSIONED_NAMESPACE_DECL
#endif /* ACE_ARRAY_MAP_CPP */

View File

@@ -0,0 +1,289 @@
// -*- C++ -*-
//=============================================================================
/**
* @file Array_Map.h
*
* Light weight array-based map with fast iteration but linear
* (i.e. O(n)) search times. STL-style interface is exposed.
*
* @note This class requires the STL generic algorithms and
* reverse_iterator adapter.
*
* @author Ossama Othman
*/
//=============================================================================
#ifndef ACE_ARRAY_MAP_H
#define ACE_ARRAY_MAP_H
#include /**/ "ace/pre.h"
#include /**/ "ace/config-lite.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include <utility>
#include <iterator>
#include <functional>
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
/**
* @class ACE_Array_Map
*
* @brief Light weight array-based map with fast iteration, but linear
* (i.e. O(n)) search times.
*
* Map implementation that focuses on small footprint and fast
* iteration. Search times are, however, linear (O(n)) meaning that
* this map isn't suitable for large data sets that will be searched
* in performance critical areas of code. Iteration over large data
* sets, however, is faster than linked list-based maps, for example,
* since spatial locality is maximized through the use of contiguous
* arrays as the underlying storage.
* @par
* An @c ACE_Array_Map is a unique associative container, meaning that
* duplicate values may not be added to the map. It is also pair
* associative (value_type is a std::pair<>). It is not a sorted
* container.
* @par
* An STL @c std::map -like interface is exposed by this class
* portability. Furthermore, this map's iterators are compatible with
* STL algorithms.
* @par
* <b> Requirements and Performance Characteristics</b>
* - Internal Structure
* Array
* - Duplicates allowed?
* No
* - Random access allowed?
* Yes
* - Search speed
* O(n)
* - Insert/replace speed
* O(n), can be longer if the map has to resize
* - Iterator still valid after change to container?
* No
* - Frees memory for removed elements?
* Yes
* - Items inserted by
* Value
* - Requirements for key type
* -# Default constructor
* -# Copy constructor
* -# operator=
* -# operator==
* - Requirements for object type
* -# Default constructor
* -# Copy constructor
* -# operator=
*/
template<typename Key, typename Value, class EqualTo = std::equal_to<Key> >
class ACE_Array_Map
{
public:
// STL-style typedefs/traits.
typedef Key key_type;
typedef Value data_type;
typedef std::pair<key_type, data_type> value_type;
typedef value_type * iterator;
typedef value_type const * const_iterator;
typedef value_type & reference;
typedef value_type const & const_reference;
typedef value_type * pointer;
typedef value_type const * const_pointer;
typedef ptrdiff_t difference_type;
typedef size_t size_type;
ACE_DECLARE_STL_REVERSE_ITERATORS
/// Default Constructor.
/**
* Create an empty map with a preallocated buffer of size @a s.
*/
ACE_Array_Map (size_type s = 0);
template<typename InputIterator>
ACE_Array_Map (InputIterator f, InputIterator l);
ACE_Array_Map (ACE_Array_Map const & map);
ACE_Array_Map & operator= (ACE_Array_Map const & map);
/// Destructor.
~ACE_Array_Map (void);
/**
* @name Forward Iterator Accessors
*
* Forward iterator accessors.
*/
//@{
iterator begin (void);
iterator end (void);
const_iterator begin (void) const;
const_iterator end (void) const;
//@}
/**
* @name Reverse Iterator Accessors
*
* Reverse iterator accessors.
*/
//@{
reverse_iterator rbegin (void);
reverse_iterator rend (void);
const_reverse_iterator rbegin (void) const;
const_reverse_iterator rend (void) const;
//@}
/// Return current size of map.
/**
* @return The number of elements in the map.
*/
size_type size (void) const;
/// Maximum number of elements the map can hold.
size_type max_size (void) const;
/// Return @c true if the map is empty, else @c false.
bool is_empty (void) const; // ACE style
/**
* Return @c true if the map is empty, else @c false. We recommend
* using @c is_empty() instead since it's more consistent with the
* ACE container naming conventions.
*/
bool empty (void) const; // STL style
/// Swap the contents of this map with the given @a map in an
/// exception-safe manner.
void swap (ACE_Array_Map & map);
/// Insert the value @a x into the map.
/**
* STL-style map insertion method.
*
* @param x @c std::pair containing key and datum.
*
* @return @c std::pair::second will be @c false if the map already
* contains a value with the same key as @a x.
*/
std::pair<iterator, bool> insert (value_type const & x);
/// Insert range of elements into map.
template<typename InputIterator>
void insert (InputIterator f, InputIterator l);
/// Remove element at position @a pos from the map.
void erase (iterator pos);
/// Remove element corresponding to key @a k from the map.
/**
* @return Number of elements that were erased.
*/
size_type erase (key_type const & k);
/// Remove range of elements [@a first, @a last) from the map.
/**
* @note [@a first, @a last) must be valid range within the map.
*/
void erase (iterator first, iterator last);
/// Clear contents of map.
/**
* @note This a constant time (O(1)) operation.
*/
void clear (void);
/**
* @name Search Operations
*
* Search the map for data corresponding to key @a k.
*/
//@{
/**
* @return @c end() if data corresponding to key @a k is not in the
* map.
*/
iterator find (key_type const & k);
/**
* @return @c end() if data corresponding to key @a k is not in the
* map.
*/
const_iterator find (key_type const & k) const;
//@}
/// Count the number of elements corresponding to key @a k.
/**
* @return In the case of this map, the count will always be one if
* such exists in the map.
*/
size_type count (key_type const & k);
/// Convenience array index operator.
/**
* Array index operator that allows insertion and retrieval of
* elements using an array index syntax, such as:
* @par
* map["Foo"] = 12;
*/
data_type & operator[] (key_type const & k);
private:
/// Increase size of underlying buffer by @a s.
void grow (size_type s);
private:
/// Number of elements in the map.
size_type size_;
/// Current size of underlying array.
/**
* @note @c capacity_ is always greater than or equal to @c size_;
*/
size_type capacity_;
/// Underlying array containing keys and data.
value_type * nodes_;
};
// --------------------------------------------------------------
/// @c ACE_Array_Map equality operator.
template <typename Key, typename Value, class EqualTo>
bool operator== (ACE_Array_Map<Key, Value, EqualTo> const & lhs,
ACE_Array_Map<Key, Value, EqualTo> const & rhs);
/// @c ACE_Array_Map lexicographical comparison operator.
template <typename Key, typename Value, class EqualTo>
bool operator< (ACE_Array_Map<Key, Value, EqualTo> const & lhs,
ACE_Array_Map<Key, Value, EqualTo> const & rhs);
// --------------------------------------------------------------
ACE_END_VERSIONED_NAMESPACE_DECL
#ifdef __ACE_INLINE__
# include "ace/Array_Map.inl"
#endif /* __ACE_INLINE__ */
#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
# include "ace/Array_Map.cpp"
#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
#pragma implementation ("Array_Map.cpp")
#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
#include /**/ "ace/post.h"
#endif /* ACE_ARRAY_MAP_H */

View File

@@ -0,0 +1,130 @@
// -*- C++ -*-
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
template<typename Key, typename Value, class EqualTo>
ACE_INLINE
ACE_Array_Map<Key, Value, EqualTo>::ACE_Array_Map (
typename ACE_Array_Map<Key, Value, EqualTo>::size_type s)
: size_ (0)
, capacity_ (s)
, nodes_ (s == 0 ? 0 : new value_type[s])
{
}
template<typename Key, typename Value, class EqualTo>
ACE_INLINE ACE_Array_Map<Key, Value, EqualTo> &
ACE_Array_Map<Key, Value, EqualTo>::operator= (
ACE_Array_Map<Key, Value, EqualTo> const & map)
{
// Strongly exception-safe assignment.
ACE_Array_Map<Key, Value, EqualTo> temp (map);
this->swap (temp);
return *this;
}
template<typename Key, typename Value, class EqualTo>
ACE_INLINE typename ACE_Array_Map<Key, Value, EqualTo>::iterator
ACE_Array_Map<Key, Value, EqualTo>::begin (void)
{
return this->nodes_;
}
template<typename Key, typename Value, class EqualTo>
ACE_INLINE typename ACE_Array_Map<Key, Value, EqualTo>::iterator
ACE_Array_Map<Key, Value, EqualTo>::end (void)
{
return this->nodes_ + this->size_;
}
template<typename Key, typename Value, class EqualTo>
ACE_INLINE typename ACE_Array_Map<Key, Value, EqualTo>::const_iterator
ACE_Array_Map<Key, Value, EqualTo>::begin (void) const
{
return this->nodes_;
}
template<typename Key, typename Value, class EqualTo>
ACE_INLINE typename ACE_Array_Map<Key, Value, EqualTo>::const_iterator
ACE_Array_Map<Key, Value, EqualTo>::end (void) const
{
return this->nodes_ + this->size_;
}
template<typename Key, typename Value, class EqualTo>
ACE_INLINE typename ACE_Array_Map<Key, Value, EqualTo>::reverse_iterator
ACE_Array_Map<Key, Value, EqualTo>::rbegin (void)
{
return reverse_iterator (this->end ());
}
template<typename Key, typename Value, class EqualTo>
ACE_INLINE typename ACE_Array_Map<Key, Value, EqualTo>::reverse_iterator
ACE_Array_Map<Key, Value, EqualTo>::rend (void)
{
return reverse_iterator (this->begin ());
}
template<typename Key, typename Value, class EqualTo>
ACE_INLINE typename ACE_Array_Map<Key, Value, EqualTo>::const_reverse_iterator
ACE_Array_Map<Key, Value, EqualTo>::rbegin (void) const
{
return const_reverse_iterator (this->end ());
}
template<typename Key, typename Value, class EqualTo>
ACE_INLINE typename ACE_Array_Map<Key, Value, EqualTo>::const_reverse_iterator
ACE_Array_Map<Key, Value, EqualTo>::rend (void) const
{
return const_reverse_iterator (this->begin ());
}
template<typename Key, typename Value, class EqualTo>
ACE_INLINE typename ACE_Array_Map<Key, Value, EqualTo>::size_type
ACE_Array_Map<Key, Value, EqualTo>::size (void) const
{
return this->size_;
}
template<typename Key, typename Value, class EqualTo>
ACE_INLINE typename ACE_Array_Map<Key, Value, EqualTo>::size_type
ACE_Array_Map<Key, Value, EqualTo>::max_size (void) const
{
return size_type (-1) / sizeof (value_type);
}
template<typename Key, typename Value, class EqualTo>
ACE_INLINE bool
ACE_Array_Map<Key, Value, EqualTo>::is_empty (void) const
{
return this->size_ == 0;
}
// The following method is deprecated.
template<typename Key, typename Value, class EqualTo>
ACE_INLINE bool
ACE_Array_Map<Key, Value, EqualTo>::empty (void) const
{
return this->is_empty ();
}
template<typename Key, typename Value, class EqualTo>
ACE_INLINE typename ACE_Array_Map<Key, Value, EqualTo>::size_type
ACE_Array_Map<Key, Value, EqualTo>::count (
typename ACE_Array_Map<Key, Value, EqualTo>::key_type const & k)
{
return
(this->find (k) == this->end () ? 0 : 1); // Only one datum per key.
}
template<typename Key, typename Value, class EqualTo>
ACE_INLINE typename ACE_Array_Map<Key, Value, EqualTo>::data_type &
ACE_Array_Map<Key, Value, EqualTo>::operator[] (
typename ACE_Array_Map<Key, Value, EqualTo>::key_type const & k)
{
iterator i = (this->insert (value_type (k, data_type ()))).first;
return (*i).second;
}
ACE_END_VERSIONED_NAMESPACE_DECL

View File

@@ -0,0 +1,20 @@
#include "ace/Assert.h"
#include "ace/Log_Category.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
// The following ASSERT macro is courtesy of Alexandre Karev
// <akg@na47sun05.cern.ch>.
void
__ace_assert(const char *file, int line, const ACE_TCHAR *expression)
{
int error = ACE_Log_Msg::last_error_adapter ();
ACE_Log_Msg *log = ACE_Log_Msg::instance ();
log->set (file, line, -1, error, log->restart (),
log->msg_ostream (), log->msg_callback ());
log->log (LM_ERROR, ACE_TEXT ("ACE_ASSERT: file %N, line %l assertion failed for '%s'.%a\n"), expression, -1);
}
ACE_END_VERSIONED_NAMESPACE_DECL

View File

@@ -0,0 +1,38 @@
// -*- C++ -*-
//=============================================================================
/**
* @file Assert.h
*
* @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
*/
//=============================================================================
#ifndef ACE_ASSERT_H
#define ACE_ASSERT_H
#include /**/ "ace/pre.h"
#include /**/ "ace/ACE_export.h"
#include /**/ "ace/config-all.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
ACE_Export void __ace_assert(const char *file, int line, const ACE_TCHAR *expression);
ACE_END_VERSIONED_NAMESPACE_DECL
#define ACE_TEST_ASSERT(X) \
((X) \
? static_cast<void>(0) \
: ACE_VERSIONED_NAMESPACE_NAME::__ace_assert(__FILE__, __LINE__, ACE_TEXT_CHAR_TO_TCHAR (#X)))
#if defined (ACE_NDEBUG)
#define ACE_ASSERT(x) \
(static_cast<void>(0))
#else
#define ACE_ASSERT(X) ACE_TEST_ASSERT(X)
#endif /* ACE_NDEBUG */
#include /**/ "ace/post.h"
#endif /* ACE_ASSERT */

View File

@@ -0,0 +1,506 @@
/* -*- C++ -*- */
#ifndef ACE_ASYNCH_ACCEPTOR_C
#define ACE_ASYNCH_ACCEPTOR_C
#include "ace/Asynch_Acceptor.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#if defined (ACE_HAS_WIN32_OVERLAPPED_IO) || defined (ACE_HAS_AIO_CALLS)
// This only works on platforms that support async i/o.
#include "ace/OS_Errno.h"
#include "ace/OS_Memory.h"
#include "ace/OS_NS_sys_socket.h"
#include "ace/Log_Category.h"
#include "ace/Message_Block.h"
#include "ace/INET_Addr.h"
#include "ace/SOCK_Stream.h"
#include "ace/Sock_Connect.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
template <class HANDLER>
ACE_Asynch_Acceptor<HANDLER>::ACE_Asynch_Acceptor (void)
: listen_handle_ (ACE_INVALID_HANDLE),
pass_addresses_ (false),
validate_new_connection_ (false),
reissue_accept_ (1),
bytes_to_read_ (0),
addr_family_ (0)
{
}
template <class HANDLER>
ACE_Asynch_Acceptor<HANDLER>::~ACE_Asynch_Acceptor (void)
{
// Close down the listen socket
if (this->listen_handle_ != ACE_INVALID_HANDLE)
{
ACE_OS::closesocket (this->listen_handle_);
this->listen_handle_ = ACE_INVALID_HANDLE;
}
}
template <class HANDLER> int
ACE_Asynch_Acceptor<HANDLER>::open (const ACE_INET_Addr &address,
size_t bytes_to_read,
bool pass_addresses,
int backlog,
int reuse_addr,
ACE_Proactor *proactor,
bool validate_new_connection,
int reissue_accept,
int number_of_initial_accepts)
{
ACE_TRACE ("ACE_Asynch_Acceptor<>::open");
this->proactor (proactor);
this->pass_addresses_ = pass_addresses;
this->bytes_to_read_ = bytes_to_read;
this->validate_new_connection_ = validate_new_connection;
this->reissue_accept_ = reissue_accept;
this->addr_family_ = address.get_type ();
// Create the listener socket
this->listen_handle_ = ACE_OS::socket (address.get_type (), SOCK_STREAM, 0);
if (this->listen_handle_ == ACE_INVALID_HANDLE)
ACELIB_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("ACE_OS::socket")),
-1);
// Initialize the ACE_Asynch_Accept
if (this->asynch_accept_.open (*this,
this->listen_handle_,
0,
this->proactor ()) == -1)
{
ACE_Errno_Guard g (errno);
ACELIB_ERROR ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("ACE_Asynch_Accept::open")));
ACE_OS::closesocket (this->listen_handle_);
this->listen_handle_ = ACE_INVALID_HANDLE;
return -1;
}
if (reuse_addr)
{
// Reuse the address
int one = 1;
if (ACE_OS::setsockopt (this->listen_handle_,
SOL_SOCKET,
SO_REUSEADDR,
(const char*) &one,
sizeof one) == -1)
{
ACE_Errno_Guard g (errno);
ACELIB_ERROR ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("ACE_OS::setsockopt")));
ACE_OS::closesocket (this->listen_handle_);
this->listen_handle_ = ACE_INVALID_HANDLE;
return -1;
}
}
// If port is not specified, bind to any port.
static ACE_INET_Addr sa (ACE_sap_any_cast (const ACE_INET_Addr &));
if (address == sa &&
ACE::bind_port (this->listen_handle_,
INADDR_ANY,
address.get_type()) == -1)
{
ACE_Errno_Guard g (errno);
ACELIB_ERROR ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("ACE::bind_port")));
ACE_OS::closesocket (this->listen_handle_);
this->listen_handle_ = ACE_INVALID_HANDLE;
return -1;
}
// Bind to the specified port.
if (ACE_OS::bind (this->listen_handle_,
reinterpret_cast<sockaddr *> (address.get_addr ()),
address.get_size ()) == -1)
{
ACE_Errno_Guard g (errno);
ACELIB_ERROR ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("ACE_OS::bind")));
ACE_OS::closesocket (this->listen_handle_);
this->listen_handle_ = ACE_INVALID_HANDLE;
return -1;
}
// Start listening.
if (ACE_OS::listen (this->listen_handle_, backlog) == -1)
{
ACE_Errno_Guard g (errno);
ACELIB_ERROR ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("ACE_OS::listen")));
ACE_OS::closesocket (this->listen_handle_);
this->listen_handle_ = ACE_INVALID_HANDLE;
return -1;
}
// For the number of <intial_accepts>.
if (number_of_initial_accepts == -1)
number_of_initial_accepts = backlog;
for (int i = 0; i < number_of_initial_accepts; i++)
{
// Initiate accepts.
if (this->accept (bytes_to_read) == -1)
{
ACE_Errno_Guard g (errno);
ACELIB_ERROR ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("ACE_Asynch_Acceptor::accept")));
ACE_OS::closesocket (this->listen_handle_);
this->listen_handle_ = ACE_INVALID_HANDLE;
return -1;
}
}
return 0;
}
template <class HANDLER> int
ACE_Asynch_Acceptor<HANDLER>::set_handle (ACE_HANDLE listen_handle)
{
ACE_TRACE ("ACE_Asynch_Acceptor<>::set_handle");
// Take ownership of the <listen_handle>
this->listen_handle_ = listen_handle;
// Reinitialize the ACE_Asynch_Accept
if (this->asynch_accept_.open (*this,
this->listen_handle_,
0,
this->proactor ()) == -1)
ACELIB_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("ACE_Asynch_Accept::open")),
-1);
return 0;
}
template <class HANDLER> ACE_HANDLE
ACE_Asynch_Acceptor<HANDLER>::get_handle (void) const
{
return this->listen_handle_;
}
template <class HANDLER> int
ACE_Asynch_Acceptor<HANDLER>::accept (size_t bytes_to_read, const void *act)
{
ACE_TRACE ("ACE_Asynch_Acceptor<>::accept");
ACE_Message_Block *message_block = 0;
// The space_needed calculation is drive by needs of Windows. POSIX doesn't
// need to extra 16 bytes, but it doesn't hurt.
size_t space_needed = sizeof (sockaddr_in) + 16;
#if defined (ACE_HAS_IPV6)
if (PF_INET6 == this->addr_family_)
space_needed = sizeof (sockaddr_in6) + 16;
#endif /* ACE_HAS_IPV6 */
space_needed = (2 * space_needed) + bytes_to_read;
// Create a new message block big enough for the addresses and data
ACE_NEW_RETURN (message_block,
ACE_Message_Block (space_needed),
-1);
// Initiate asynchronous accepts
if (this->asynch_accept_.accept (*message_block,
bytes_to_read,
ACE_INVALID_HANDLE,
act,
0,
ACE_SIGRTMIN,
this->addr_family_) == -1)
{
// Cleanup on error
message_block->release ();
return -1;
}
return 0;
}
template <class HANDLER> void
ACE_Asynch_Acceptor<HANDLER>::handle_accept (const ACE_Asynch_Accept::Result &result)
{
ACE_TRACE ("ACE_Asynch_Acceptor<>::handle_accept");
// Variable for error tracking
int error = 0;
// If the asynchronous accept fails.
if (!result.success () || result.accept_handle () == ACE_INVALID_HANDLE)
{
error = 1;
}
#if defined (ACE_WIN32)
// In order to use accept handle with other Window Sockets 1.1
// functions, we call the setsockopt function with the
// SO_UPDATE_ACCEPT_CONTEXT option. This option initializes the
// socket so that other Windows Sockets routines to access the
// socket correctly.
if (!error &&
ACE_OS::setsockopt (result.accept_handle (),
SOL_SOCKET,
SO_UPDATE_ACCEPT_CONTEXT,
(char *) &this->listen_handle_,
sizeof (this->listen_handle_)) == -1)
{
error = 1;
}
#endif /* ACE_WIN32 */
// Parse address.
ACE_INET_Addr local_address;
ACE_INET_Addr remote_address;
if (!error &&
(this->validate_new_connection_ || this->pass_addresses_))
// Parse the addresses.
this->parse_address (result,
remote_address,
local_address);
// Validate remote address
if (!error &&
this->validate_new_connection_ &&
(this->validate_connection (result, remote_address, local_address) == -1))
{
error = 1;
}
HANDLER *new_handler = 0;
if (!error)
{
// The Template method
new_handler = this->make_handler ();
if (new_handler == 0)
{
error = 1;
}
}
// If no errors
if (!error)
{
// Update the Proactor unless make_handler() or constructed handler
// set up its own.
if (new_handler->proactor () == 0)
new_handler->proactor (this->proactor ());
// Pass the addresses
if (this->pass_addresses_)
new_handler->addresses (remote_address,
local_address);
// Pass the ACT
if (result.act () != 0)
new_handler->act (result.act ());
// Set up the handler's new handle value
new_handler->handle (result.accept_handle ());
// Initiate the handler
new_handler->open (result.accept_handle (),
result.message_block ());
}
// On failure, no choice but to close the socket
if (error &&
result.accept_handle() != ACE_INVALID_HANDLE )
ACE_OS::closesocket (result.accept_handle ());
// Delete the dynamically allocated message_block
result.message_block ().release ();
// Start off another asynchronous accept to keep the backlog going,
// unless we closed the listen socket already (from the destructor),
// or this callback is the result of a canceled/aborted accept.
if (this->should_reissue_accept () &&
this->listen_handle_ != ACE_INVALID_HANDLE
#if defined (ACE_WIN32)
&& result.error () != ERROR_OPERATION_ABORTED
#else
&& result.error () != ECANCELED
#endif
)
this->accept (this->bytes_to_read_, result.act ());
}
template <class HANDLER> int
ACE_Asynch_Acceptor<HANDLER>::validate_connection
(const ACE_Asynch_Accept::Result& /* result */,
const ACE_INET_Addr& /* remote */,
const ACE_INET_Addr& /* local */)
{
// Default implementation always validates the remote address.
return 0;
}
template <class HANDLER> int
ACE_Asynch_Acceptor<HANDLER>::cancel (void)
{
ACE_TRACE ("ACE_Asynch_Acceptor<>::cancel");
// All I/O operations that are canceled will complete with the error
// ERROR_OPERATION_ABORTED. All completion notifications for the I/O
// operations will occur normally.
#if defined (ACE_HAS_WIN32_OVERLAPPED_IO)
return (int) ::CancelIo (this->listen_handle_);
#else
// Supported now
return this->asynch_accept_.cancel();
#endif /* defined (ACE_HAS_WIN32_OVERLAPPED_IO) */
}
template <class HANDLER> void
ACE_Asynch_Acceptor<HANDLER>::parse_address (const
ACE_Asynch_Accept::Result &result,
ACE_INET_Addr &remote_address,
ACE_INET_Addr &local_address)
{
ACE_TRACE ("ACE_Asynch_Acceptor<>::parse_address");
#if defined (ACE_HAS_AIO_CALLS)
// Use an ACE_SOCK to get the addresses - it knows how to deal with
// ACE_INET_Addr objects and get IPv4/v6 addresses.
ACE_SOCK_Stream str (result.accept_handle ());
str.get_local_addr (local_address);
str.get_remote_addr (remote_address);
#elif defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
ACE_Message_Block &message_block = result.message_block ();
sockaddr *local_addr = 0;
sockaddr *remote_addr = 0;
int local_size = 0;
int remote_size = 0;
// This matches setup in accept().
size_t addr_size = sizeof (sockaddr_in) + 16;
#if defined (ACE_HAS_IPV6)
if (this->addr_family_ == PF_INET6)
addr_size = sizeof (sockaddr_in6) + 16;
#endif /* ACE_HAS_IPV6 */
::GetAcceptExSockaddrs (message_block.rd_ptr (),
static_cast<DWORD> (this->bytes_to_read_),
static_cast<DWORD> (addr_size),
static_cast<DWORD> (addr_size),
&local_addr,
&local_size,
&remote_addr,
&remote_size);
local_address.set (reinterpret_cast<sockaddr_in *> (local_addr),
local_size);
remote_address.set (reinterpret_cast<sockaddr_in *> (remote_addr),
remote_size);
#else
// just in case
errno = ENOTSUP;
#endif /* defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) */
return;
}
template <class HANDLER> ACE_HANDLE
ACE_Asynch_Acceptor<HANDLER>::handle (void) const
{
return this->listen_handle_;
}
template <class HANDLER> void
ACE_Asynch_Acceptor<HANDLER>::handle (ACE_HANDLE h)
{
ACE_Handler::handle (h);
}
template <class HANDLER> ACE_Asynch_Accept &
ACE_Asynch_Acceptor<HANDLER>::asynch_accept (void)
{
return this->asynch_accept_;
}
template <class HANDLER> HANDLER *
ACE_Asynch_Acceptor<HANDLER>::make_handler (void)
{
// Default behavior
HANDLER *handler = 0;
ACE_NEW_RETURN (handler,
HANDLER,
0);
return handler;
}
template <class HANDLER> bool
ACE_Asynch_Acceptor<HANDLER>::pass_addresses (void) const
{
return this->pass_addresses_;
}
template <class HANDLER> void
ACE_Asynch_Acceptor<HANDLER>::pass_addresses (bool new_value)
{
this->pass_addresses_ = new_value;
}
template <class HANDLER> bool
ACE_Asynch_Acceptor<HANDLER>::validate_new_connection (void) const
{
return this->validate_new_connection_;
}
template <class HANDLER> void
ACE_Asynch_Acceptor<HANDLER>::validate_new_connection (bool new_value)
{
this->validate_new_connection_ = new_value;
}
template <class HANDLER> int
ACE_Asynch_Acceptor<HANDLER>::reissue_accept (void) const
{
return this->reissue_accept_;
}
template <class HANDLER> void
ACE_Asynch_Acceptor<HANDLER>::reissue_accept (int new_value)
{
this->reissue_accept_ = new_value;
}
template <class HANDLER> size_t
ACE_Asynch_Acceptor<HANDLER>::bytes_to_read (void) const
{
return this->bytes_to_read_;
}
template <class HANDLER> void
ACE_Asynch_Acceptor<HANDLER>::bytes_to_read (size_t new_value)
{
this->bytes_to_read_ = new_value;
}
template <class HANDLER> int
ACE_Asynch_Acceptor<HANDLER>::should_reissue_accept (void)
{
return this->reissue_accept_;
}
ACE_END_VERSIONED_NAMESPACE_DECL
#endif /* ACE_WIN32 || ACE_HAS_AIO_CALLS */
#endif /* ACE_ASYNCH_ACCEPTOR_C */

View File

@@ -0,0 +1,274 @@
/* -*- C++ -*- */
//=============================================================================
/**
* @file Asynch_Acceptor.h
*
* @author Irfan Pyarali (irfan@cs.wustl.edu)
*/
//=============================================================================
#ifndef ACE_ASYNCH_ACCEPTOR_H
#define ACE_ASYNCH_ACCEPTOR_H
#include /**/ "ace/pre.h"
#include /**/ "ace/config-all.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#if defined (ACE_HAS_WIN32_OVERLAPPED_IO) || defined (ACE_HAS_AIO_CALLS)
// This only works on platforms that support async i/o.
#include "ace/Default_Constants.h"
#include "ace/Asynch_IO.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
// Forward declarations
class ACE_Message_Block;
class ACE_INET_Addr;
/**
* @class ACE_Asynch_Acceptor
*
* @brief This class is an example of the Acceptor Pattern. This class
* will accept new connections and create new HANDLER to handle
* the new connections.
*
* Unlike the ACE_Acceptor, however, this class is designed to
* be used asynchronously.
*/
template <class HANDLER>
class ACE_Asynch_Acceptor : public ACE_Handler
{
public:
/// A do nothing constructor.
ACE_Asynch_Acceptor (void);
/// Virtual destruction
virtual ~ACE_Asynch_Acceptor (void);
/**
* @c open starts one or more asynchronous accept requests on a
* @a address. Each accept operation may optionally read an
* initial buffer from the new connection when accepted.
*
* @param address The address to listen/accept connections on.
* If the address does not specify a port, a random
* port is selected and bound.
* @param bytes_to_read Optional, specifies the maximum number of bytes
* to read with the accept. The buffer for the initial
* data is allocated internally and passed to the
* @c ACE_Service_Handler::open() hook method. It is
* legitimate only during the @c open() method and must
* be copied if required after @c open() returns.
* This pre-read function works only on Windows.
* @param pass_addresses Optional, a non-zero value indicates that
* the local and peer addresses should be passed to the
* associated @c ACE_Service_Handler::addresses() method
* after any call to @c validate_new_connection() and prior
* to the @c open() hook method call.
* @param backlog Optional, defaulting to @c ACE_DEFAULT_ASYNCH_BACKLOG (which
* can be adjusted in your platform's @c config.h file).
* Specifies the listening backlog for the listening socket.
* @param reuse_addr Optional, indicates whether the @c SO_REUSEADDR
* option is set on the listening socket or not.
* @param proactor Optional, pointer to the @c ACE_Proactor to use for
* demultiplexing asynchronous accepts. If 0, the
* process's singleton @c ACE_Proactor is used.
* @param validate_new_connection Optional, if true, this object's
* @c validate_connection() method is called after
* the accept completes, but before the service handler's
* @c open() hook method is called. If @c
* validate_connection() returns -1, the newly-accepted
* socket is immediately closed, and the @c addresses()
* method is not called.
* @param reissue_accept Optional, if non-zero (the default), a new
* asynchronous accept operation is started after each
* completion, whether the completion is for success or
* failure, and whether or not a successfully-accepted
* connection is subsequently refused.
* @param number_of_initial_accepts Optional, the number of asynchronous
* accepts that are started immediately. If -1 (the
* default), the value of @a backlog is used.
*
* @note On Windows, the peer address is only available at the time
* the connection is accepted. Therefore, if you require the peer
* address on Windows, do not rely on the
* @c ACE_SOCK::get_remote_addr() method - it won't work. You must
* supply a non-zero value for @a pass_addresses and obtain the
* peer address in the @c ACE_Service_Handler::addresses() method.
*
* @see ACE_INET_Addr
* @see ACE_Service_Handler
*/
virtual int open (const ACE_INET_Addr &address,
size_t bytes_to_read = 0,
bool pass_addresses = false,
int backlog = ACE_DEFAULT_ASYNCH_BACKLOG,
int reuse_addr = 1,
ACE_Proactor *proactor = 0,
bool validate_new_connection = false,
int reissue_accept = 1,
int number_of_initial_accepts = -1);
/// Get the underlying handle.
virtual ACE_HANDLE get_handle (void) const;
/**
* Set the underlying listen handle. It is the user's responsibility
* to make sure that the old listen handle has been appropriately
* closed and the all outstanding asynchronous operations have
* either completed or have been canceled on the old listen handle.
*/
virtual int set_handle (ACE_HANDLE handle);
/// This initiates a new asynchronous accept operation.
/**
* You need only call this method if the @a reissue_accept argument
* passed to @c open() was 0.
*/
virtual int accept (size_t bytes_to_read = 0, const void *act = 0);
/**
* Cancels all pending accepts operations issued by this object.
*
* @note On Windows, only accept operations initiated by the calling thread
* are canceled.
*/
virtual int cancel (void);
/**
* Template method to validate peer before service is opened.
* This method is called after a new connection is accepted if the
* @a validate_connection argument to @c open() was non-zero or
* the @c validate_new_connection() method is called to turn this
* feature on. The default implementation returns 0. Users can
* reimplement this method to perform validation of the peer
* using it's address, running an authentication procedure (such as
* SSL) or anything else necessary or desireable. The return value
* from this method determines whether or not ACE will continue
* opening the service or abort the connection.
*
* @param result Result of the connection acceptance.
* @param remote Peer's address.
* @param local Local address connection was accepted at.
*
* @retval -1 ACE_Asynch_Acceptor will close the connection, and
* the service will not be opened.
* @retval 0 Service opening will proceeed.
*/
virtual int validate_connection (const ACE_Asynch_Accept::Result& result,
const ACE_INET_Addr &remote,
const ACE_INET_Addr& local);
/**
* Template method for deciding whether to reissue accept.
*
* This hook method is called after each accept completes to decide if
* another accept should be initiated. If the method returns a non-zero
* value, another accept is initiated.
*
* The default implemenation always returns the value passed as the
* @c open() method's @a reissue_accept argument. That value can also
* be changed using the @c reissue_accept() method.
*/
virtual int should_reissue_accept (void);
//
// These are low level tweaking methods
//
/// Get flag that indicates if parsing and passing of addresses to
/// the service_handler is necessary.
virtual bool pass_addresses (void) const;
/// Set flag that indicates if parsing and passing of addresses to
/// the service_handler is necessary.
virtual void pass_addresses (bool new_value);
/// Get flag that indicates if address validation is required.
virtual bool validate_new_connection (void) const;
/// Set flag that indicates if address validation is required.
virtual void validate_new_connection (bool new_value);
/// Get flag that indicates if a new accept should be reissued when a accept
/// completes.
virtual int reissue_accept (void) const;
/// Set flag that indicates if a new accept should be reissued when a accept
/// completes.
virtual void reissue_accept (int new_value);
/// Get bytes to be read with the <accept> call.
virtual size_t bytes_to_read (void) const;
/// Set bytes to be read with the <accept> call.
virtual void bytes_to_read (size_t new_value);
protected:
/// This is called when an outstanding accept completes.
virtual void handle_accept (const ACE_Asynch_Accept::Result &result);
/// Return the listen handle.
ACE_HANDLE handle (void) const;
/// Set the listen handle.
void handle (ACE_HANDLE h);
/// This parses the address from read buffer.
void parse_address (const ACE_Asynch_Accept::Result &result,
ACE_INET_Addr &remote_address,
ACE_INET_Addr &local_address);
/// Return the asynch accept object.
ACE_Asynch_Accept &asynch_accept (void);
/**
* This is the template method used to create new handler.
* Subclasses must overwrite this method if a new handler creation
* strategy is required.
*/
virtual HANDLER *make_handler (void);
private:
/// Handle used to listen for new connections.
ACE_HANDLE listen_handle_;
/// Asynch_Accept used to make life easier :-)
ACE_Asynch_Accept asynch_accept_;
/// Flag that indicates if parsing of addresses is necessary.
bool pass_addresses_;
/// Flag that indicates if address validation is required.
bool validate_new_connection_;
/// Flag that indicates if a new accept should be reissued when a
/// accept completes.
int reissue_accept_;
/// Bytes to be read with the <accept> call.
size_t bytes_to_read_;
/// Address family used to open this object. Obtained from @a address passed
/// to @c open().
int addr_family_;
};
ACE_END_VERSIONED_NAMESPACE_DECL
#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
#include "ace/Asynch_Acceptor.cpp"
#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
#pragma implementation ("Asynch_Acceptor.cpp")
#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
#endif /* ACE_HAS_WIN32_OVERLAPPED_IO || ACE_HAS_AIO_CALLS */
#include /**/ "ace/post.h"
#endif /* ACE_ASYNCH_ACCEPTOR_H */

View File

@@ -0,0 +1,268 @@
#ifndef ACE_ASYNCH_CONNECTOR_CPP
#define ACE_ASYNCH_CONNECTOR_CPP
#include "ace/Asynch_Connector.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#if (defined (ACE_WIN32) || defined (ACE_HAS_AIO_CALLS)) && !defined(ACE_HAS_WINCE)
// This only works on platforms that support async I/O.
#include "ace/OS_NS_sys_socket.h"
#include "ace/OS_Memory.h"
#include "ace/Flag_Manip.h"
#include "ace/Log_Category.h"
#include "ace/Message_Block.h"
#include "ace/INET_Addr.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
template <class HANDLER>
ACE_Asynch_Connector<HANDLER>::ACE_Asynch_Connector (void)
: pass_addresses_ (false),
validate_new_connection_ (false)
{
}
template <class HANDLER>
ACE_Asynch_Connector<HANDLER>::~ACE_Asynch_Connector (void)
{
//this->asynch_connect_.close ();
}
template <class HANDLER> int
ACE_Asynch_Connector<HANDLER>::open (bool pass_addresses,
ACE_Proactor *proactor,
bool validate_new_connection)
{
this->proactor (proactor);
this->pass_addresses_ = pass_addresses;
this->validate_new_connection_ = validate_new_connection;
// Initialize the ACE_Asynch_Connect
if (this->asynch_connect_.open (*this,
ACE_INVALID_HANDLE,
0,
this->proactor ()) == -1)
ACELIB_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("ACE_Asynch_Connect::open")),
-1);
return 0;
}
template <class HANDLER> int
ACE_Asynch_Connector<HANDLER>::connect (const ACE_INET_Addr & remote_sap,
const ACE_INET_Addr & local_sap,
int reuse_addr,
const void *act)
{
// Initiate asynchronous connect
if (this->asynch_connect_.connect (ACE_INVALID_HANDLE,
remote_sap,
local_sap,
reuse_addr,
act) == -1)
ACELIB_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("ACE_Asynch_Connect::connect")),
-1);
return 0;
}
template <class HANDLER> void
ACE_Asynch_Connector<HANDLER>::handle_connect (const ACE_Asynch_Connect::Result &result)
{
// Variable for error tracking
int error = 0;
// If the asynchronous connect fails.
if (!result.success () ||
result.connect_handle () == ACE_INVALID_HANDLE)
{
error = 1;
}
if (result.error () != 0)
{
error = 1;
}
// set blocking mode
if (!error &&
ACE::clr_flags
(result.connect_handle (), ACE_NONBLOCK) != 0)
{
error = 1;
ACELIB_ERROR ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("ACE_Asynch_Connector::handle_connect : Set blocking mode")));
}
// Parse the addresses.
ACE_INET_Addr local_address;
ACE_INET_Addr remote_address;
if (!error &&
(this->validate_new_connection_ || this->pass_addresses_))
this->parse_address (result,
remote_address,
local_address);
// Call validate_connection even if there was an error - it's the only
// way the application can learn the connect disposition.
if (this->validate_new_connection_ &&
this->validate_connection (result, remote_address, local_address) == -1)
{
error = 1;
}
HANDLER *new_handler = 0;
if (!error)
{
// The Template method
new_handler = this->make_handler ();
if (new_handler == 0)
{
error = 1;
ACELIB_ERROR ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("ACE_Asynch_Connector::handle_connect : Making of new handler failed")));
}
}
// If no errors
if (!error)
{
// Update the Proactor.
new_handler->proactor (this->proactor ());
// Pass the addresses
if (this->pass_addresses_)
new_handler->addresses (remote_address,
local_address);
// Pass the ACT
if (result.act () != 0)
new_handler->act (result.act ());
// Set up the handler's new handle value
new_handler->handle (result.connect_handle ());
ACE_Message_Block mb;
// Initiate the handler with empty message block;
new_handler->open (result.connect_handle (), mb);
}
// On failure, no choice but to close the socket
if (error &&
result.connect_handle() != ACE_INVALID_HANDLE)
ACE_OS::closesocket (result.connect_handle ());
}
template <class HANDLER> int
ACE_Asynch_Connector<HANDLER>::validate_connection
(const ACE_Asynch_Connect::Result &,
const ACE_INET_Addr & /* remote_address */,
const ACE_INET_Addr & /* local_address */)
{
// Default implementation always validates the remote address.
return 0;
}
template <class HANDLER> int
ACE_Asynch_Connector<HANDLER>::cancel (void)
{
return this->asynch_connect_.cancel ();
}
template <class HANDLER> void
ACE_Asynch_Connector<HANDLER>::parse_address (const ACE_Asynch_Connect::Result &result,
ACE_INET_Addr &remote_address,
ACE_INET_Addr &local_address)
{
#if defined (ACE_HAS_IPV6)
// Getting the addresses.
sockaddr_in6 local_addr;
sockaddr_in6 remote_addr;
#else
// Getting the addresses.
sockaddr_in local_addr;
sockaddr_in remote_addr;
#endif /* ACE_HAS_IPV6 */
// Get the length.
int local_size = sizeof (local_addr);
int remote_size = sizeof (remote_addr);
// Get the local address.
if (ACE_OS::getsockname (result.connect_handle (),
reinterpret_cast<sockaddr *> (&local_addr),
&local_size) < 0)
ACELIB_ERROR ((LM_ERROR,
ACE_TEXT("%p\n"),
ACE_TEXT("ACE_Asynch_Connector::<getsockname> failed")));
// Get the remote address.
if (ACE_OS::getpeername (result.connect_handle (),
reinterpret_cast<sockaddr *> (&remote_addr),
&remote_size) < 0)
ACELIB_ERROR ((LM_ERROR,
ACE_TEXT("%p\n"),
ACE_TEXT("ACE_Asynch_Connector::<getpeername> failed")));
// Set the addresses.
local_address.set (reinterpret_cast<sockaddr_in *> (&local_addr),
local_size);
remote_address.set (reinterpret_cast<sockaddr_in *> (&remote_addr),
remote_size);
return;
}
template <class HANDLER> ACE_Asynch_Connect &
ACE_Asynch_Connector<HANDLER>::asynch_connect (void)
{
return this->asynch_connect_;
}
template <class HANDLER> HANDLER *
ACE_Asynch_Connector<HANDLER>::make_handler (void)
{
// Default behavior
HANDLER *handler = 0;
ACE_NEW_RETURN (handler, HANDLER, 0);
return handler;
}
template <class HANDLER> bool
ACE_Asynch_Connector<HANDLER>::pass_addresses (void) const
{
return this->pass_addresses_;
}
template <class HANDLER> void
ACE_Asynch_Connector<HANDLER>::pass_addresses (bool new_value)
{
this->pass_addresses_ = new_value;
}
template <class HANDLER> bool
ACE_Asynch_Connector<HANDLER>::validate_new_connection (void) const
{
return this->validate_new_connection_;
}
template <class HANDLER> void
ACE_Asynch_Connector<HANDLER>::validate_new_connection (bool new_value)
{
this->validate_new_connection_ = new_value;
}
ACE_END_VERSIONED_NAMESPACE_DECL
#endif /* ACE_WIN32 || ACE_HAS_AIO_CALLS */
#endif /* ACE_ASYNCH_CONNECTOR_CPP */

View File

@@ -0,0 +1,169 @@
/* -*- C++ -*- */
//=============================================================================
/**
* @file Asynch_Connector.h
*
* @author Alexander Libman <alibman@ihug.com.au>
*/
//=============================================================================
#ifndef ACE_ASYNCH_CONNECTOR_H
#define ACE_ASYNCH_CONNECTOR_H
#include /**/ "ace/pre.h"
#include /**/ "ace/config-all.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#if (defined (ACE_WIN32) || defined (ACE_HAS_AIO_CALLS)) && !defined(ACE_HAS_WINCE)
// This only works on platforms that support async i/o.
#include "ace/Asynch_IO.h"
#include "ace/INET_Addr.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
// Forward declarations
class ACE_Message_Block;
/**
* @class ACE_Asynch_Connector
*
* @brief This class is an example of the Connector pattern. This class
* will establish new connections and create new HANDLER objects to handle
* the new connections.
*
* Unlike the ACE_Connector, however, this class is designed to
* be used asynchronously with the ACE Proactor framework.
*/
template <class HANDLER>
class ACE_Asynch_Connector : public ACE_Handler
{
public:
/// A do nothing constructor.
ACE_Asynch_Connector (void);
/// Virtual destruction
virtual ~ACE_Asynch_Connector (void);
/**
* This opens asynch connector
*/
virtual int open (bool pass_addresses = false,
ACE_Proactor *proactor = 0,
bool validate_new_connection = true);
/// This initiates a new asynchronous connect
virtual int connect (const ACE_INET_Addr &remote_sap,
const ACE_INET_Addr &local_sap =
(const ACE_INET_Addr &)ACE_Addr::sap_any,
int reuse_addr = 1,
const void *act = 0);
/**
* This cancels all pending accepts operations that were issued by
* the calling thread.
*
* @note On Windows, this method does not cancel connect operations
* issued by other threads.
*
* @note On POSIX, delegates cancelation to ACE_POSIX_Asynch_Connect.
*/
virtual int cancel (void);
/**
* Template method to validate peer before service is opened.
* This method is called when the connection attempt completes,
* whether it succeeded or failed, if the @a validate_connection
* argument to @c open() was non-zero or the @c validate_new_connection()
* method is called to turn this feature on. The default implementation
* returns 0. Users can (and probably should) reimplement this method
* to learn about the success or failure of the connection attempt.
* If the connection completed successfully, this method can be used to
* perform validation of the peer using it's address, running an
* authentication procedure (such as SSL) or anything else necessary or
* desireable. The return value from this method determines whether or
* not ACE will continue opening the service or abort the connection.
*
* @param result Result of the connection acceptance. Use
* result.success() to determine success or failure of
* the connection attempt.
* @param remote Peer's address. If the connection failed, this object
* is undefined.
* @param local Local address connection was completed from. If the
* connection failed, this object is undefined.
*
* @retval -1 ACE_Asynch_Connector will close the connection, and
* the service will not be opened.
* @retval 0 Service opening will proceeed.
* @return Return value is ignored if the connection attempt failed.
*/
virtual int validate_connection (const ACE_Asynch_Connect::Result& result,
const ACE_INET_Addr &remote,
const ACE_INET_Addr& local);
//
// These are low level tweaking methods
//
/// Set and get flag that indicates if parsing and passing of
/// addresses to the service_handler is necessary.
virtual bool pass_addresses (void) const;
virtual void pass_addresses (bool new_value);
/// Set and get flag that indicates if address validation is
/// required.
virtual bool validate_new_connection (void) const;
virtual void validate_new_connection (bool new_value);
protected:
/// This is called when an outstanding accept completes.
virtual void handle_connect (const ACE_Asynch_Connect::Result &result);
/// This parses the address from read buffer.
void parse_address (const ACE_Asynch_Connect::Result &result,
ACE_INET_Addr &remote_address,
ACE_INET_Addr &local_address);
/// Return the asynch Connect object.
ACE_Asynch_Connect & asynch_connect (void);
/**
* This is the template method used to create new handler.
* Subclasses must overwrite this method if a new handler creation
* strategy is required.
*/
virtual HANDLER *make_handler (void);
private:
/// Asynch_Connect used to make life easier :-)
ACE_Asynch_Connect asynch_connect_;
/// Flag that indicates if parsing of addresses is necessary.
bool pass_addresses_;
/// Flag that indicates if address validation is required.
bool validate_new_connection_;
};
ACE_END_VERSIONED_NAMESPACE_DECL
#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
#include "ace/Asynch_Connector.cpp"
#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
#pragma implementation ("Asynch_Connector.cpp")
#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
#endif /* ACE_WIN32 || ACE_HAS_AIO_CALLS */
#include /**/ "ace/post.h"
#endif /* ACE_ASYNCH_CONNECTOR_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,115 @@
#include "ace/Asynch_IO_Impl.h"
#if defined (ACE_HAS_WIN32_OVERLAPPED_IO) || defined (ACE_HAS_AIO_CALLS)
// This only works on Win32 platforms and on Unix platforms supporting
// aio calls.
#if !defined (__ACE_INLINE__)
#include "ace/Asynch_IO_Impl.inl"
#endif /* __ACE_INLINE__ */
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
ACE_Asynch_Result_Impl::~ACE_Asynch_Result_Impl (void)
{
}
ACE_Asynch_Operation_Impl::~ACE_Asynch_Operation_Impl (void)
{
}
ACE_Asynch_Read_Stream_Impl::~ACE_Asynch_Read_Stream_Impl (void)
{
}
ACE_Asynch_Read_Stream_Result_Impl::~ACE_Asynch_Read_Stream_Result_Impl (void)
{
}
ACE_Asynch_Write_Stream_Impl::~ACE_Asynch_Write_Stream_Impl (void)
{
}
ACE_Asynch_Write_Stream_Result_Impl::~ACE_Asynch_Write_Stream_Result_Impl (void)
{
}
ACE_Asynch_Read_File_Impl::~ACE_Asynch_Read_File_Impl (void)
{
}
ACE_Asynch_Write_File_Impl::~ACE_Asynch_Write_File_Impl (void)
{
}
ACE_Asynch_Read_File_Result_Impl::~ACE_Asynch_Read_File_Result_Impl (void)
{
}
ACE_Asynch_Write_File_Result_Impl::~ACE_Asynch_Write_File_Result_Impl (void)
{
}
ACE_Asynch_Accept_Result_Impl::~ACE_Asynch_Accept_Result_Impl (void)
{
}
ACE_Asynch_Connect_Result_Impl::~ACE_Asynch_Connect_Result_Impl (void)
{
}
ACE_Asynch_Accept_Impl::~ACE_Asynch_Accept_Impl (void)
{
}
ACE_Asynch_Connect_Impl::~ACE_Asynch_Connect_Impl (void)
{
}
ACE_Asynch_Transmit_File_Impl::~ACE_Asynch_Transmit_File_Impl (void)
{
}
ACE_Asynch_Transmit_File_Result_Impl::~ACE_Asynch_Transmit_File_Result_Impl (void)
{
}
ACE_Asynch_Read_Dgram_Impl::~ACE_Asynch_Read_Dgram_Impl (void)
{
}
ACE_Asynch_Read_Dgram_Impl::ACE_Asynch_Read_Dgram_Impl (void)
{
}
ACE_Asynch_Write_Dgram_Impl::~ACE_Asynch_Write_Dgram_Impl (void)
{
}
ACE_Asynch_Write_Dgram_Impl::ACE_Asynch_Write_Dgram_Impl (void)
{
}
//***********************************************
ACE_Asynch_Read_Dgram_Result_Impl::~ACE_Asynch_Read_Dgram_Result_Impl (void)
{
}
ACE_Asynch_Read_Dgram_Result_Impl::ACE_Asynch_Read_Dgram_Result_Impl (void)
{
}
//***********************************************
ACE_Asynch_Write_Dgram_Result_Impl::~ACE_Asynch_Write_Dgram_Result_Impl (void)
{
}
ACE_Asynch_Write_Dgram_Result_Impl::ACE_Asynch_Write_Dgram_Result_Impl (void)
{
}
ACE_END_VERSIONED_NAMESPACE_DECL
#endif /* ACE_HAS_WIN32_OVERLAPPED_IO || ACE_HAS_AIO_CALLS */

View File

@@ -0,0 +1,793 @@
/* -*- C++ -*- */
//=============================================================================
/**
* @file Asynch_IO_Impl.h
*
* This class contains asbtract base classes for all the concrete
* implementation classes for the various asynchronous operations
* that are used with the Praoctor.
*
* @author Irfan Pyarali (irfan@cs.wustl.edu)
* @author Tim Harrison (harrison@cs.wustl.edu)
* @author Alexander Babu Arulanthu <alex@cs.wustl.edu>
* @author Roger Tragin <r.tragin@computer.org>
* @author Alexander Libman <alibman@ihug.com.au>
*/
//=============================================================================
#ifndef ACE_ASYNCH_IO_IMPL_H
#define ACE_ASYNCH_IO_IMPL_H
#include /**/ "ace/pre.h"
#include /**/ "ace/config-all.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
#pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#if defined (ACE_HAS_WIN32_OVERLAPPED_IO) || defined (ACE_HAS_AIO_CALLS)
// This only works on Win32 platforms and on Unix platforms supporting
// aio calls.
#include "ace/Asynch_IO.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
// Forward declaration.
class ACE_Proactor_Impl;
/**
* @class ACE_Asynch_Result_Impl
*
* @brief Abstract base class for the all the classes that provide
* concrete implementations for ACE_Asynch_Result.
*/
class ACE_Export ACE_Asynch_Result_Impl
{
public:
virtual ~ACE_Asynch_Result_Impl (void);
/// Number of bytes transferred by the operation.
virtual size_t bytes_transferred (void) const = 0;
/// ACT associated with the operation.
virtual const void *act (void) const = 0;
/// Did the operation succeed?
virtual int success (void) const = 0;
/// This ACT is not the same as the ACT associated with the
/// asynchronous operation.
virtual const void *completion_key (void) const = 0;
/// Error value if the operation fail.
virtual u_long error (void) const = 0;
/// Event associated with the OVERLAPPED structure.
virtual ACE_HANDLE event (void) const = 0;
/// This really make sense only when doing file I/O.
virtual u_long offset (void) const = 0;
virtual u_long offset_high (void) const = 0;
/// Priority of the operation.
virtual int priority (void) const = 0;
/**
* POSIX4 real-time signal number to be used for the
* operation. signal_number ranges from SIGRTMIN to SIGRTMAX. By
* default, SIGRTMIN is used to issue <aio_> calls. This is a no-op
* on non-POSIX4 systems and returns 0.
*/
virtual int signal_number (void) const = 0;
// protected:
//
// These two should really be protected. But sometimes it
// simplifies code to be able to "fake" a result. Use carefully.
/// This is called when the asynchronous operation completes.
virtual void complete (size_t bytes_transferred,
int success,
const void *completion_key,
u_long error = 0) = 0;
/// Post @c this to the Proactor's completion port.
virtual int post_completion (ACE_Proactor_Impl *proactor) = 0;
protected:
/// Do-nothing constructor.
ACE_Asynch_Result_Impl (void);
};
/**
* @class ACE_Asynch_Operation_Impl
*
* @brief Abstract base class for all the concrete implementation
* classes that provide different implementations for the
* ACE_Asynch_Operation.
*/
class ACE_Export ACE_Asynch_Operation_Impl
{
public:
virtual ~ACE_Asynch_Operation_Impl (void);
/**
* Initializes the factory with information which will be used with
* each asynchronous call. If @a handle == ACE_INVALID_HANDLE,
* ACE_Handler::handle() will be called on the proxied handler to get the
* correct handle.
*/
virtual int open (const ACE_Handler::Proxy_Ptr &handler_proxy,
ACE_HANDLE handle,
const void *completion_key,
ACE_Proactor *proactor) = 0;
/**
* This cancels all pending accepts operations that were issued by
* the calling thread. The function does not cancel asynchronous
* operations issued by other threads.
*/
virtual int cancel (void) = 0;
// = Access methods.
/// Return the underlying proactor.
virtual ACE_Proactor* proactor (void) const = 0;
protected:
/// Do-nothing constructor.
ACE_Asynch_Operation_Impl (void);
};
/**
* @class ACE_Asynch_Read_Stream_Impl
*
* @brief Abstract base class for all the concrete implementation
* classes that provide different implementations for the
* ACE_Asynch_Read_Stream
*/
class ACE_Export ACE_Asynch_Read_Stream_Impl : public virtual ACE_Asynch_Operation_Impl
{
public:
virtual ~ACE_Asynch_Read_Stream_Impl (void);
/// This starts off an asynchronous read. Upto @a bytes_to_read will
/// be read and stored in the @a message_block.
virtual int read (ACE_Message_Block &message_block,
size_t bytes_to_read,
const void *act,
int priority,
int signal_number) = 0;
#if (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE))
/**
* Same as above but with scatter support, through chaining of composite
* message blocks using the continuation field.
*/
virtual int readv (ACE_Message_Block &message_block,
size_t bytes_to_read,
const void *act,
int priority,
int signal_number) = 0;
#endif /* (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) */
protected:
/// Do-nothing constructor.
ACE_Asynch_Read_Stream_Impl (void);
};
/**
* @class ACE_Asynch_Read_Stream_Result_Impl
*
* @brief Abstract base class for all the concrete implementation
* classes that provide different implementations for the
* ACE_Asynch_Read_Stream::Result class.
*/
class ACE_Export ACE_Asynch_Read_Stream_Result_Impl : public virtual ACE_Asynch_Result_Impl
{
public:
virtual ~ACE_Asynch_Read_Stream_Result_Impl (void);
/// The number of bytes which were requested at the start of the
/// asynchronous read.
virtual size_t bytes_to_read (void) const = 0;
/// Message block which contains the read data.
virtual ACE_Message_Block &message_block (void) const = 0;
/// I/O handle used for reading.
virtual ACE_HANDLE handle (void) const = 0;
protected:
/// Do-nothing constructor.
ACE_Asynch_Read_Stream_Result_Impl (void);
};
/**
* @class ACE_Asynch_Write_Stream_Impl
*
* @brief Abstract base class for all the concrete implementation
* classes that provide different implementations for the
* ACE_Asynch_Write_Stream class.
*/
class ACE_Export ACE_Asynch_Write_Stream_Impl : public virtual ACE_Asynch_Operation_Impl
{
public:
virtual ~ACE_Asynch_Write_Stream_Impl (void);
/// This starts off an asynchronous write. Upto @a bytes_to_write
/// will be written from the @a message_block.
virtual int write (ACE_Message_Block &message_block,
size_t bytes_to_write,
const void *act,
int priority,
int signal_number) = 0;
#if (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE))
/**
* Same as above but with gather support, through chaining of composite
* message blocks using the continuation field.
*/
virtual int writev (ACE_Message_Block &message_block,
size_t bytes_to_write,
const void *act,
int priority,
int signal_number) = 0;
#endif /* (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) */
protected:
/// Do-nothing constructor.
ACE_Asynch_Write_Stream_Impl (void);
};
/**
* @class ACE_Asynch_Write_Stream_Result_Impl
*
* @brief Abstract base class for all the concrete implementation
* classes that provide different implementations for the
* ACE_Asynch_Write_Stream::Result.
*/
class ACE_Export ACE_Asynch_Write_Stream_Result_Impl : public virtual ACE_Asynch_Result_Impl
{
public:
virtual ~ACE_Asynch_Write_Stream_Result_Impl (void);
/// The number of bytes which were requested at the start of the
/// asynchronous write.
virtual size_t bytes_to_write (void) const = 0;
/// Message block that contains the data to be written.
virtual ACE_Message_Block &message_block (void) const = 0;
/// I/O handle used for writing.
virtual ACE_HANDLE handle (void) const = 0;
protected:
/// Do-nothing constructor.
ACE_Asynch_Write_Stream_Result_Impl (void);
};
/**
* @class ACE_Asynch_Read_File_Impl
*
* @brief Abstract base class for all the concrete implementation
* classes that provide different implementations for the
* ACE_Asynch_Read_File::Result.
*/
class ACE_Export ACE_Asynch_Read_File_Impl : public virtual ACE_Asynch_Read_Stream_Impl
{
public:
virtual ~ACE_Asynch_Read_File_Impl (void);
/**
* This starts off an asynchronous read. Upto @a bytes_to_read will
* be read and stored in the @a message_block. The read will start
* at @a offset from the beginning of the file.
*/
virtual int read (ACE_Message_Block &message_block,
size_t bytes_to_read,
u_long offset,
u_long offset_high,
const void *act,
int priority,
int signal_number) = 0;
#if (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE))
/**
* Same as above but with scatter support, through chaining of composite
* message blocks using the continuation field.
* @note In win32 Each data block payload must be at least the size of a system
* memory page and must be aligned on a system memory page size boundary
*/
virtual int readv (ACE_Message_Block &message_block,
size_t bytes_to_read,
u_long offset,
u_long offset_high,
const void *act,
int priority,
int signal_number) = 0;
#endif /* (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) */
/// This starts off an asynchronous read. Upto @a bytes_to_read will
/// be read and stored in the @a message_block.
virtual int read (ACE_Message_Block &message_block,
size_t bytes_to_read,
const void *act,
int priority,
int signal_number) = 0;
#if (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE))
/**
* Same as above but with scatter support, through chaining of composite
* message blocks using the continuation field.
*/
virtual int readv (ACE_Message_Block &message_block,
size_t bytes_to_read,
const void *act,
int priority,
int signal_number) = 0;
#endif /* (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) */
protected:
/// Do-nothing constructor.
ACE_Asynch_Read_File_Impl (void);
};
/**
* @class ACE_Asynch_Read_File_Result_Impl
*
* @brief This is the abstract base class for all the concrete
* implementation classes for ACE_Asynch_Read_File::Result.
*/
class ACE_Export ACE_Asynch_Read_File_Result_Impl : public virtual ACE_Asynch_Read_Stream_Result_Impl
{
public:
/// Destructor.
virtual ~ACE_Asynch_Read_File_Result_Impl (void);
protected:
/// Do-nothing constructor.
ACE_Asynch_Read_File_Result_Impl (void);
};
/**
* @class ACE_Asynch_Write_File_Impl
*
* @brief Abstract base class for all the concrete implementation
* classes that provide different implementations for the
* ACE_Asynch_Write_File.
*/
class ACE_Export ACE_Asynch_Write_File_Impl : public virtual ACE_Asynch_Write_Stream_Impl
{
public:
virtual ~ACE_Asynch_Write_File_Impl (void);
/**
* This starts off an asynchronous write. Upto @a bytes_to_write
* will be write and stored in the @a message_block. The write will
* start at @a offset from the beginning of the file.
*/
virtual int write (ACE_Message_Block &message_block,
size_t bytes_to_write,
u_long offset,
u_long offset_high,
const void *act,
int priority,
int signal_number) = 0;
#if (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE))
/**
* Same as above but with gather support, through chaining of composite
* message blocks using the continuation field.
* @note In win32 Each data block payload must be at least the size of a system
* memory page and must be aligned on a system memory page size boundary
*/
virtual int writev (ACE_Message_Block &message_block,
size_t bytes_to_write,
u_long offset,
u_long offset_high,
const void *act,
int priority,
int signal_number) = 0;
#endif /* (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) */
/// This starts off an asynchronous write. Upto @a bytes_to_write
/// will be written from the @a message_block.
virtual int write (ACE_Message_Block &message_block,
size_t bytes_to_write,
const void *act,
int priority,
int signal_number) = 0;
#if (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE))
/**
* Same as above but with gather support, through chaining of composite
* message blocks using the continuation field.
*/
virtual int writev (ACE_Message_Block &message_block,
size_t bytes_to_write,
const void *act,
int priority,
int signal_number) = 0;
#endif /* (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) */
protected:
/// Do-nothing constructor.
ACE_Asynch_Write_File_Impl (void);
};
/**
* @class ACE_Asynch_Write_File_Result_Impl
*
* @brief This is the abstract base class for all the concrete
* implementation classes that provide different implementations
* for the ACE_Asynch_Write_File::Result.
*/
class ACE_Export ACE_Asynch_Write_File_Result_Impl : public virtual ACE_Asynch_Write_Stream_Result_Impl
{
public:
virtual ~ACE_Asynch_Write_File_Result_Impl (void);
protected:
/// Do-nothing constructor.
ACE_Asynch_Write_File_Result_Impl (void);
};
/**
* @class ACE_Asynch_Accept_Impl
*
* @brief Abstract base class for all the concrete implementation
* classes that provide different implementations for the
* ACE_Asynch_Accept.
*/
class ACE_Export ACE_Asynch_Accept_Impl : public virtual ACE_Asynch_Operation_Impl
{
public:
virtual ~ACE_Asynch_Accept_Impl (void);
/**
* This starts off an asynchronous accept. The asynchronous accept
* call also allows any initial data to be returned to the
* <handler>. Upto @a bytes_to_read will be read and stored in the
* @a message_block. The @a accept_handle will be used for the
* <accept> call. If (@a accept_handle == INVALID_HANDLE), a new
* handle will be created.
*
* @a message_block must be specified. This is because the address of
* the new connection is placed at the end of this buffer.
*/
virtual int accept (ACE_Message_Block &message_block,
size_t bytes_to_read,
ACE_HANDLE accept_handle,
const void *act,
int priority,
int signal_number,
int addr_family) = 0;
protected:
/// Do-nothing constructor.
ACE_Asynch_Accept_Impl (void);
};
/**
* @class ACE_Asynch_Accept_Result_Impl
*
* @brief Abstract base class for all the concrete implementation
* classes that provide different implementations for the
* ACE_Asynch_Accept.
*/
class ACE_Export ACE_Asynch_Accept_Result_Impl : public virtual ACE_Asynch_Result_Impl
{
public:
virtual ~ACE_Asynch_Accept_Result_Impl (void);
/// The number of bytes which were requested at the start of the
/// asynchronous accept.
virtual size_t bytes_to_read (void) const = 0;
/// Message block which contains the read data.
virtual ACE_Message_Block &message_block (void) const = 0;
/// I/O handle used for accepting new connections.
virtual ACE_HANDLE listen_handle (void) const = 0;
/// I/O handle for the new connection.
virtual ACE_HANDLE accept_handle (void) const = 0;
protected:
/// Do-nothing constructor.
ACE_Asynch_Accept_Result_Impl (void);
};
/**
* @class ACE_Asynch_Connect_Impl
*
* @brief Abstract base class for all the concrete implementation
* classes that provide different implementations for the
* ACE_Asynch_Connect.
*/
class ACE_Export ACE_Asynch_Connect_Impl : public virtual ACE_Asynch_Operation_Impl
{
public:
virtual ~ACE_Asynch_Connect_Impl (void);
/**
* This starts off an asynchronous connect
*/
virtual int connect (ACE_HANDLE connect_handle,
const ACE_Addr & remote_sap,
const ACE_Addr & local_sap,
int reuse_addr,
const void *act,
int priority,
int signal_number) = 0;
protected:
/// Do-nothing constructor.
ACE_Asynch_Connect_Impl (void);
};
/**
* @class ACE_Asynch_Connect_Result_Impl
*
* @brief Abstract base class for all the concrete implementation
* classes that provide different implementations for the
* ACE_Asynch_Connect.
*/
class ACE_Export ACE_Asynch_Connect_Result_Impl : public virtual ACE_Asynch_Result_Impl
{
public:
virtual ~ACE_Asynch_Connect_Result_Impl (void);
/// I/O handle for the connection.
virtual ACE_HANDLE connect_handle (void) const = 0;
protected:
/// Do-nothing constructor.
ACE_Asynch_Connect_Result_Impl (void);
};
/**
* @class ACE_Asynch_Transmit_File_Impl
*
* @brief Abstract base class for all the concrete implementation
* classes that provide different implementations for the
* ACE_Asynch_Transmit_File.
*/
class ACE_Asynch_Transmit_File_Impl : public virtual ACE_Asynch_Operation_Impl
{
public:
virtual ~ACE_Asynch_Transmit_File_Impl (void);
/// This starts off an asynchronous transmit file.
virtual int transmit_file (ACE_HANDLE file,
ACE_Asynch_Transmit_File::Header_And_Trailer *header_and_trailer,
size_t bytes_to_write,
u_long offset,
u_long offset_high,
size_t bytes_per_send,
u_long flags,
const void *act,
int priority,
int signal_number) = 0;
protected:
/// Do-nothing constructor.
ACE_Asynch_Transmit_File_Impl (void);
};
/**
* @class ACE_Asynch_Transmit_File_Result_Impl
*
* @brief Abstract base class for all the concrete implementation
* classes that provide different implementations for the
* ACE_Asynch_Transmit_File::Result.
*/
class ACE_Export ACE_Asynch_Transmit_File_Result_Impl : public virtual ACE_Asynch_Result_Impl
{
public:
virtual ~ACE_Asynch_Transmit_File_Result_Impl (void);
/// Socket used for transmitting the file.
virtual ACE_HANDLE socket (void) const = 0;
/// File from which the data is read.
virtual ACE_HANDLE file (void) const = 0;
/// Header and trailer data associated with this transmit file.
virtual ACE_Asynch_Transmit_File::Header_And_Trailer *header_and_trailer (void) const = 0;
/// The number of bytes which were requested at the start of the
/// asynchronous transmit file.
virtual size_t bytes_to_write (void) const = 0;
/// Number of bytes per send requested at the start of the transmit
/// file.
virtual size_t bytes_per_send (void) const = 0;
/// Flags which were passed into transmit file.
virtual u_long flags (void) const = 0;
protected:
/// Do-nothing constructor.
ACE_Asynch_Transmit_File_Result_Impl (void);
};
/**
* @class ACE_Asynch_Read_Dgram_Impl
*
* @brief Abstract base class for all the concrete implementation
* classes that provide different implementations for the
* ACE_Asynch_Read_Dgram
*/
class ACE_Export ACE_Asynch_Read_Dgram_Impl : public virtual ACE_Asynch_Operation_Impl
{
public:
virtual ~ACE_Asynch_Read_Dgram_Impl (void);
/** This starts off an asynchronous read. Upto
* <message_block->total_size()> will be read and stored in the
* @a message_block. @a message_block's <wr_ptr> will be updated to reflect
* the added bytes if the read operation is successful completed.
* Return code of 1 means immediate success and <number_of_bytes_recvd>
* will contain number of bytes read. The <ACE_Handler::handle_read_dgram>
* method will still be called. Return code of 0 means the IO will
* complete proactively. Return code of -1 means there was an error, use
* errno to get the error code.
*
* Scatter/gather is supported on WIN32 by using the <message_block->cont()>
* method. Up to ACE_IOV_MAX @a message_block's are supported. Upto
* <message_block->size()> bytes will be read into each <message block> for
* a total of <message_block->total_size()> bytes. All @a message_block's
* <wr_ptr>'s will be updated to reflect the added bytes for each
* @a message_block
*
* Priority of the operation is specified by @a priority. On POSIX4-Unix,
* this is supported. Works like <nice> in Unix. Negative values are not
* allowed. 0 means priority of the operation same as the process
* priority. 1 means priority of the operation is one less than
* process. And so forth. On Win32, @a priority is a no-op.
* @a signal_number is the POSIX4 real-time signal number to be used
* for the operation. @a signal_number ranges from ACE_SIGRTMIN to
* ACE_SIGRTMAX. This argument is a no-op on non-POSIX4 systems.
*/
virtual ssize_t recv (ACE_Message_Block *message_block,
size_t &number_of_bytes_recvd,
int flags,
int protocol_family,
const void *act,
int priority,
int signal_number) = 0;
protected:
/// Do-nothing constructor.
ACE_Asynch_Read_Dgram_Impl (void);
};
/**
* @class ACE_Asynch_Read_Dgram_Result_Impl
*
* @brief Abstract base class for all the concrete implementation
* classes that provide different implementations for the
* ACE_Asynch_Read_Dgram::Result class.
*/
class ACE_Export ACE_Asynch_Read_Dgram_Result_Impl : public virtual ACE_Asynch_Result_Impl
{
public:
virtual ~ACE_Asynch_Read_Dgram_Result_Impl (void);
/// Message block which contains the read data
virtual ACE_Message_Block *message_block (void) const = 0;
/// The number of bytes which were requested at the start of the
/// asynchronous read.
virtual size_t bytes_to_read (void) const = 0;
/// The address of where the packet came from
virtual int remote_address (ACE_Addr& addr) const = 0;
/// The flags used in the read
virtual int flags (void) const = 0;
/// I/O handle used for reading.
virtual ACE_HANDLE handle (void) const = 0;
protected:
/// Do-nothing constructor.
ACE_Asynch_Read_Dgram_Result_Impl (void);
};
/**
* @class ACE_Asynch_Write_Dgram_Impl
*
* @brief Abstract base class for all the concrete implementation
* classes that provide different implementations for the
* ACE_Asynch_Write_Dgram class.
*/
class ACE_Export ACE_Asynch_Write_Dgram_Impl : public virtual ACE_Asynch_Operation_Impl
{
public:
virtual ~ACE_Asynch_Write_Dgram_Impl (void);
/** This starts off an asynchronous send. Upto
* <message_block->total_length()> will be sent. @a message_block's
* <rd_ptr> will be updated to reflect the sent bytes if the send operation
* is successful completed.
* Return code of 1 means immediate success and <number_of_bytes_sent>
* is updated to number of bytes sent. The <ACE_Handler::handle_write_dgram>
* method will still be called. Return code of 0 means the IO will
* complete proactively. Return code of -1 means there was an error, use
* errno to get the error code.
*
* Scatter/gather is supported on WIN32 by using the <message_block->cont()>
* method. Up to ACE_IOV_MAX @a message_block's are supported. Upto
* <message_block->length()> bytes will be sent from each <message block>
* for a total of <message_block->total_length()> bytes. All
* @a message_block's <rd_ptr>'s will be updated to reflect the bytes sent
* from each @a message_block.
*
* Priority of the operation is specified by @a priority. On POSIX4-Unix,
* this is supported. Works like <nice> in Unix. Negative values are not
* allowed. 0 means priority of the operation same as the process
* priority. 1 means priority of the operation is one less than
* process. And so forth. On Win32, this argument is a no-op.
* @a signal_number is the POSIX4 real-time signal number to be used
* for the operation. @a signal_number ranges from ACE_SIGRTMIN to
* ACE_SIGRTMAX. This argument is a no-op on non-POSIX4 systems.
*/
virtual ssize_t send (ACE_Message_Block *message_block,
size_t &number_of_bytes_sent,
int flags,
const ACE_Addr &addr,
const void *act,
int priority,
int signal_number) = 0;
protected:
/// Do-nothing constructor.
ACE_Asynch_Write_Dgram_Impl (void);
};
/**
* @class ACE_Asynch_Write_Dgram_Result_Impl
*
* @brief Abstract base class for all the concrete implementation
* classes that provide different implementations for the
* ACE_Asynch_Write_Dgram::Result class.
*/
class ACE_Export ACE_Asynch_Write_Dgram_Result_Impl : public virtual ACE_Asynch_Result_Impl
{
public:
virtual ~ACE_Asynch_Write_Dgram_Result_Impl (void);
/// The number of bytes which were requested at the start of the
/// asynchronous write.
virtual size_t bytes_to_write (void) const = 0;
/// Message block which contains the sent data
virtual ACE_Message_Block *message_block (void) const = 0;
/// The flags using in the write
virtual int flags (void) const = 0;
/// I/O handle used for writing.
virtual ACE_HANDLE handle (void) const = 0;
protected:
/// Do-nothing constructor.
ACE_Asynch_Write_Dgram_Result_Impl (void);
};
ACE_END_VERSIONED_NAMESPACE_DECL
#if defined (__ACE_INLINE__)
#include "ace/Asynch_IO_Impl.inl"
#endif /* __ACE_INLINE__ */
#endif /* ACE_HAS_WIN32_OVERLAPPED_IO || ACE_HAS_AIO_CALLS */
#include /**/ "ace/post.h"
#endif /* ACE_ASYNCH_IO_IMPL_H */

View File

@@ -0,0 +1,103 @@
// -*- C++ -*-
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
ACE_INLINE
ACE_Asynch_Result_Impl::ACE_Asynch_Result_Impl (void)
{
}
ACE_INLINE
ACE_Asynch_Operation_Impl::ACE_Asynch_Operation_Impl (void)
{
}
ACE_INLINE
ACE_Asynch_Read_Stream_Impl::ACE_Asynch_Read_Stream_Impl (void)
: ACE_Asynch_Operation_Impl ()
{
}
ACE_INLINE
ACE_Asynch_Read_Stream_Result_Impl::ACE_Asynch_Read_Stream_Result_Impl (void)
: ACE_Asynch_Result_Impl ()
{
}
ACE_INLINE
ACE_Asynch_Write_Stream_Impl::ACE_Asynch_Write_Stream_Impl (void)
: ACE_Asynch_Operation_Impl ()
{
}
ACE_INLINE
ACE_Asynch_Write_Stream_Result_Impl::ACE_Asynch_Write_Stream_Result_Impl (void)
: ACE_Asynch_Result_Impl ()
{
}
ACE_INLINE
ACE_Asynch_Read_File_Impl::ACE_Asynch_Read_File_Impl (void)
: ACE_Asynch_Operation_Impl (),
ACE_Asynch_Read_Stream_Impl ()
{
}
ACE_INLINE
ACE_Asynch_Read_File_Result_Impl::ACE_Asynch_Read_File_Result_Impl (void)
: ACE_Asynch_Result_Impl (),
ACE_Asynch_Read_Stream_Result_Impl ()
{
}
ACE_INLINE
ACE_Asynch_Write_File_Impl::ACE_Asynch_Write_File_Impl (void)
: ACE_Asynch_Operation_Impl (),
ACE_Asynch_Write_Stream_Impl ()
{
}
ACE_INLINE
ACE_Asynch_Write_File_Result_Impl::ACE_Asynch_Write_File_Result_Impl (void)
: ACE_Asynch_Result_Impl (),
ACE_Asynch_Write_Stream_Result_Impl ()
{
}
ACE_INLINE
ACE_Asynch_Accept_Impl::ACE_Asynch_Accept_Impl (void)
: ACE_Asynch_Operation_Impl ()
{
}
ACE_INLINE
ACE_Asynch_Accept_Result_Impl::ACE_Asynch_Accept_Result_Impl (void)
: ACE_Asynch_Result_Impl ()
{
}
ACE_INLINE
ACE_Asynch_Connect_Impl::ACE_Asynch_Connect_Impl (void)
: ACE_Asynch_Operation_Impl ()
{
}
ACE_INLINE
ACE_Asynch_Connect_Result_Impl::ACE_Asynch_Connect_Result_Impl (void)
: ACE_Asynch_Result_Impl ()
{
}
ACE_INLINE
ACE_Asynch_Transmit_File_Impl::ACE_Asynch_Transmit_File_Impl (void)
: ACE_Asynch_Operation_Impl ()
{
}
ACE_INLINE
ACE_Asynch_Transmit_File_Result_Impl::ACE_Asynch_Transmit_File_Result_Impl (void)
: ACE_Asynch_Result_Impl ()
{
}
ACE_END_VERSIONED_NAMESPACE_DECL

View File

@@ -0,0 +1,126 @@
#include "ace/Asynch_Pseudo_Task.h"
#include "ace/OS_NS_errno.h"
#include "ace/OS_NS_signal.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
ACE_Asynch_Pseudo_Task::ACE_Asynch_Pseudo_Task ()
: select_reactor_ (), // should be initialized before reactor_
reactor_ (&select_reactor_, 0) // don't delete implementation
{
}
ACE_Asynch_Pseudo_Task::~ACE_Asynch_Pseudo_Task ()
{
this->stop ();
}
int
ACE_Asynch_Pseudo_Task::start (void)
{
if (this->reactor_.initialized () == 0)
ACELIB_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%N:%l:%p\n"),
ACE_TEXT ("start reactor is not initialized")),
-1);
return this->activate () == -1 ? -1 : 0; // If started, return 0
}
int
ACE_Asynch_Pseudo_Task::stop (void)
{
if (this->thr_count () == 0) // already stopped
return 0;
if (this->reactor_.end_reactor_event_loop () == -1)
return -1;
this->wait ();
this->reactor_.close ();
return 0;
}
int
ACE_Asynch_Pseudo_Task::svc (void)
{
#if !defined (ACE_WIN32)
sigset_t RT_signals;
sigemptyset (&RT_signals);
for (int si = ACE_SIGRTMIN; si <= ACE_SIGRTMAX; si++)
sigaddset (&RT_signals, si);
if (ACE_OS::pthread_sigmask (SIG_BLOCK, &RT_signals, 0) != 0)
ACELIB_ERROR ((LM_ERROR,
ACE_TEXT ("Error:(%P | %t):%p\n"),
ACE_TEXT ("pthread_sigmask")));
#endif
reactor_.owner (ACE_Thread::self ());
reactor_.run_reactor_event_loop ();
return 0;
}
int
ACE_Asynch_Pseudo_Task::register_io_handler (ACE_HANDLE handle,
ACE_Event_Handler *handler,
ACE_Reactor_Mask mask,
int flg_suspend)
{
// Register the handler with the reactor.
if (-1 == this->reactor_.register_handler (handle, handler, mask))
return -1;
if (flg_suspend == 0)
return 0;
// Suspend the handle now. Enable only when the accept is issued
// by the application.
if (this->reactor_.suspend_handler (handle) == -1)
{
ACELIB_ERROR
((LM_ERROR,
ACE_TEXT ("%N:%l:%p\n"),
ACE_TEXT ("register_io_handler (suspended)")));
this->reactor_.remove_handler (handle, ACE_Event_Handler::ALL_EVENTS_MASK
| ACE_Event_Handler::DONT_CALL);
return -1;
}
return 0;
}
int
ACE_Asynch_Pseudo_Task::remove_io_handler (ACE_HANDLE handle)
{
return this->reactor_.remove_handler (handle,
ACE_Event_Handler::ALL_EVENTS_MASK
| ACE_Event_Handler::DONT_CALL);
}
int
ACE_Asynch_Pseudo_Task::remove_io_handler (ACE_Handle_Set &set)
{
return this->reactor_.remove_handler (set, ACE_Event_Handler::ALL_EVENTS_MASK
| ACE_Event_Handler::DONT_CALL);
}
int
ACE_Asynch_Pseudo_Task::suspend_io_handler (ACE_HANDLE handle)
{
return this->reactor_.suspend_handler (handle);
}
int
ACE_Asynch_Pseudo_Task::resume_io_handler (ACE_HANDLE handle)
{
return this->reactor_.resume_handler (handle);
}
ACE_END_VERSIONED_NAMESPACE_DECL

View File

@@ -0,0 +1,70 @@
// -*- C++ -*-
//=============================================================================
/**
* @file Asynch_Pseudo_Task.h
*
* @author Alexander Libman <alibman@ihug.com.au>
*/
//=============================================================================
#ifndef ACE_ASYNCH_PSEUDO_TASK_H
#define ACE_ASYNCH_PSEUDO_TASK_H
#include /**/ "ace/pre.h"
#include /**/ "ace/config-all.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
#pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "ace/Reactor.h"
#include "ace/Select_Reactor.h"
#include "ace/Task.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
/*
* Specialization hook to replace the Reactor with the
* concrete Reactor implementation, e.g., select_st,
* select_mt etc.
*/
//@@ REACTOR_SPL_INCLUDE_FORWARD_DECL_ADD_HOOK
/**
* @class ACE_Asynch_Pseudo_Task
*/
class ACE_Export ACE_Asynch_Pseudo_Task : public ACE_Task<ACE_NULL_SYNCH>
{
public:
ACE_Asynch_Pseudo_Task();
virtual ~ACE_Asynch_Pseudo_Task();
int start (void);
int stop (void);
int register_io_handler (ACE_HANDLE handle,
ACE_Event_Handler *handler,
ACE_Reactor_Mask mask,
int flg_suspend);
int remove_io_handler (ACE_HANDLE handle);
int remove_io_handler (ACE_Handle_Set &set);
int resume_io_handler (ACE_HANDLE handle);
int suspend_io_handler (ACE_HANDLE handle);
protected:
virtual int svc (void);
/// Should be initialized before reactor_
ACE_Select_Reactor select_reactor_;
ACE_Reactor reactor_;
};
ACE_END_VERSIONED_NAMESPACE_DECL
#include /**/ "ace/post.h"
#endif /* ACE_ASYNCH_PSEUDO_TASK_H */

View File

@@ -0,0 +1,304 @@
#include "ace/Atomic_Op.h"
#include "ace/OS_NS_unistd.h"
#if !defined (__ACE_INLINE__)
#include "ace/Atomic_Op.inl"
#endif /* __ACE_INLINE__ */
#if defined (ACE_HAS_BUILTIN_ATOMIC_OP)
#if defined (ACE_INCLUDE_ATOMIC_OP_SPARC)
# include "ace/Atomic_Op_Sparc.h"
#endif /* ACE_INCLUDE_ATOMIC_OP_SPARC */
namespace {
#if defined (_MSC_VER)
// Disable "no return value" warning, as we will be putting
// the return values directly into the EAX register.
#pragma warning (push)
#pragma warning (disable: 4035)
#endif /* _MSC_VER */
long
single_cpu_increment (volatile long *value)
{
#if defined (ACE_HAS_INTEL_ASSEMBLY)
long tmp = 1;
unsigned long addr = reinterpret_cast<unsigned long> (value);
asm( "xadd %0, (%1)" : "+r"(tmp) : "r"(addr) );
return tmp + 1;
#elif !defined (ACE_HAS_SOLARIS_ATOMIC_LIB) && (defined (sun) || \
(defined (__SUNPRO_CC) && (defined (__i386) || defined (__x86_64))))
return ace_atomic_add_long (
reinterpret_cast<volatile unsigned long*> (value), 1);
#elif defined(__GNUC__) && defined(PPC)
long tmp;
asm("lwz %0,%1" : "=r" (tmp) : "m" (*value) );
asm("addi %0,%0,1" : "+r" (tmp) );
asm("stw %0,%1" : "+r" (tmp), "=m" (*value) );
return tmp;
#else /* ACE_HAS_INTEL_ASSEMBLY*/
ACE_UNUSED_ARG (value);
ACE_NOTSUP_RETURN (-1);
#endif /* ACE_HAS_INTEL_ASSEMBLY*/
}
long
single_cpu_decrement (volatile long *value)
{
#if defined (ACE_HAS_INTEL_ASSEMBLY)
long tmp = -1;
unsigned long addr = reinterpret_cast<unsigned long> (value);
asm( "xadd %0, (%1)" : "+r"(tmp) : "r"(addr) );
return tmp - 1;
#elif !defined (ACE_HAS_SOLARIS_ATOMIC_LIB) && (defined (sun) || \
(defined (__SUNPRO_CC) && (defined (__i386) || defined (__x86_64))))
return ace_atomic_add_long (
reinterpret_cast<volatile unsigned long*> (value), -1);
#elif defined(__GNUC__) && defined(PPC)
long tmp;
asm("lwz %0,%1" : "=r" (tmp) : "m" (*value) );
asm("addi %0,%0,-1" : "+r" (tmp) );
asm("stw %0,%1" : "+r" (tmp), "=m" (*value) );
return tmp;
#else /* ACE_HAS_INTEL_ASSEMBLY*/
ACE_UNUSED_ARG (value);
ACE_NOTSUP_RETURN (-1);
#endif /* ACE_HAS_INTEL_ASSEMBLY*/
}
long
single_cpu_exchange (volatile long *value, long rhs)
{
#if defined (ACE_HAS_INTEL_ASSEMBLY)
unsigned long addr = reinterpret_cast<unsigned long> (value);
asm( "xchg %0, (%1)" : "+r"(rhs) : "r"(addr) );
return rhs;
#elif !defined (ACE_HAS_SOLARIS_ATOMIC_LIB) && (defined (sun) || \
(defined (__SUNPRO_CC) && (defined (__i386) || defined (__x86_64))))
return ace_atomic_swap_long (
reinterpret_cast<volatile unsigned long*> (value), rhs);
#elif defined(__GNUC__) && defined(PPC)
long tmp;
asm("lwz %0,%1" : "=r" (tmp) : "m" (rhs) );
asm("stw %0,%1" : "+r" (tmp), "=m" (*value) );
return tmp;
#else /* ACE_HAS_INTEL_ASSEMBLY*/
ACE_UNUSED_ARG (value);
ACE_UNUSED_ARG (rhs);
ACE_NOTSUP_RETURN (-1);
#endif /* ACE_HAS_INTEL_ASSEMBLY*/
}
long
single_cpu_exchange_add (volatile long *value, long rhs)
{
#if defined (ACE_HAS_INTEL_ASSEMBLY)
unsigned long addr = reinterpret_cast<unsigned long> (value);
asm( "xadd %0, (%1)" : "+r"(rhs) : "r"(addr) );
return rhs;
#elif !defined (ACE_HAS_SOLARIS_ATOMIC_LIB) && (defined (sun) || \
(defined (__SUNPRO_CC) && (defined (__i386) || defined (__x86_64))))
return ace_atomic_swap_add_long (
reinterpret_cast<volatile unsigned long*> (value), rhs);
#elif defined(__GNUC__) && defined(PPC)
long tmp;
asm("add %0,%1,%2" : "=r" (tmp) : "r" (*value), "r" (rhs) );
asm("stw %0,%1" : "+r" (tmp), "=m" (*value) );
return tmp;
#elif defined (WIN32) && !defined (ACE_HAS_INTERLOCKED_EXCHANGEADD)
# if defined (_MSC_VER)
__asm
{
mov eax, rhs
mov edx, value
xadd [edx], eax
}
// Return value is already in EAX register.
# elif defined (__BORLANDC__)
_EAX = rhs;
_EDX = reinterpret_cast<unsigned long> (value);
__emit__(0x0F, 0xC1, 0x02); // xadd [edx], eax
// Return value is already in EAX register.
# else /* _MSC_VER */
ACE_UNUSED_ARG (value);
ACE_UNUSED_ARG (rhs);
ACE_NOTSUP_RETURN (-1);
# endif /* _MSC_VER */
#else /* ACE_HAS_INTEL_ASSEMBLY*/
ACE_UNUSED_ARG (value);
ACE_UNUSED_ARG (rhs);
ACE_NOTSUP_RETURN (-1);
#endif /* ACE_HAS_INTEL_ASSEMBLY*/
}
long
multi_cpu_increment (volatile long *value)
{
#if defined (ACE_HAS_INTEL_ASSEMBLY)
long tmp = 1;
unsigned long addr = reinterpret_cast<unsigned long> (value);
asm( "lock ; xadd %0, (%1)" : "+r"(tmp) : "r"(addr) );
return tmp + 1;
#elif !defined (ACE_HAS_SOLARIS_ATOMIC_LIB) && (defined (sun) || \
(defined (__SUNPRO_CC) && (defined (__i386) || defined (__x86_64))))
return ace_atomic_add_long (
reinterpret_cast<volatile unsigned long*> (value), 1);
#else /* ACE_HAS_INTEL_ASSEMBLY*/
ACE_UNUSED_ARG (value);
ACE_NOTSUP_RETURN (-1);
#endif /* ACE_HAS_INTEL_ASSEMBLY*/
}
long
multi_cpu_decrement (volatile long *value)
{
#if defined (ACE_HAS_INTEL_ASSEMBLY)
long tmp = -1;
unsigned long addr = reinterpret_cast<unsigned long> (value);
asm( "lock ; xadd %0, (%1)" : "+r"(tmp) : "r"(addr) );
return tmp - 1;
#elif !defined (ACE_HAS_SOLARIS_ATOMIC_LIB) && (defined (sun) || \
(defined (__SUNPRO_CC) && (defined (__i386) || defined (__x86_64))))
return ace_atomic_add_long (
reinterpret_cast<volatile unsigned long*> (value), -1);
#else /* ACE_HAS_INTEL_ASSEMBLY*/
ACE_UNUSED_ARG (value);
ACE_NOTSUP_RETURN (-1);
#endif /* ACE_HAS_INTEL_ASSEMBLY*/
}
long
multi_cpu_exchange (volatile long *value, long rhs)
{
#if defined (ACE_HAS_INTEL_ASSEMBLY)
unsigned long addr = reinterpret_cast<unsigned long> (value);
// The XCHG instruction automatically follows LOCK semantics
asm( "xchg %0, (%1)" : "+r"(rhs) : "r"(addr) );
return rhs;
#elif !defined (ACE_HAS_SOLARIS_ATOMIC_LIB) && (defined (sun) || \
(defined (__SUNPRO_CC) && (defined (__i386) || defined (__x86_64))))
return ace_atomic_swap_long (
reinterpret_cast<volatile unsigned long*> (value), rhs);
#else /* ACE_HAS_INTEL_ASSEMBLY*/
ACE_UNUSED_ARG (value);
ACE_UNUSED_ARG (rhs);
ACE_NOTSUP_RETURN (-1);
#endif /* ACE_HAS_INTEL_ASSEMBLY*/
}
long
multi_cpu_exchange_add (volatile long *value, long rhs)
{
#if defined (ACE_HAS_INTEL_ASSEMBLY)
unsigned long addr = reinterpret_cast<unsigned long> (value);
asm( "lock ; xadd %0, (%1)" : "+r"(rhs) : "r"(addr) );
return rhs;
#elif !defined (ACE_HAS_SOLARIS_ATOMIC_LIB) && (defined (sun) || \
(defined (__SUNPRO_CC) && (defined (__i386) || defined (__x86_64))))
return ace_atomic_swap_add_long (
reinterpret_cast<volatile unsigned long*> (value), rhs);
#elif defined (WIN32) && !defined (ACE_HAS_INTERLOCKED_EXCHANGEADD)
# if defined (_MSC_VER)
__asm
{
mov eax, rhs
mov edx, value
lock xadd [edx], eax
}
// Return value is already in EAX register.
# elif defined (__BORLANDC__)
_EAX = rhs;
_EDX = reinterpret_cast<unsigned long> (value);
__emit__(0xF0, 0x0F, 0xC1, 0x02); // lock xadd [edx], eax
// Return value is already in EAX register.
# else /* _MSC_VER */
ACE_UNUSED_ARG (value);
ACE_UNUSED_ARG (rhs);
ACE_NOTSUP_RETURN (-1);
# endif /* _MSC_VER */
#else /* ACE_HAS_INTEL_ASSEMBLY*/
ACE_UNUSED_ARG (value);
ACE_UNUSED_ARG (rhs);
ACE_NOTSUP_RETURN (-1);
#endif /* ACE_HAS_INTEL_ASSEMBLY*/
}
#if defined (_MSC_VER)
#pragma warning (pop)
#endif /* _MSC_VER */
} // end namespace
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
long (*ACE_Atomic_Op<ACE_Thread_Mutex, long>::increment_fn_) (volatile long *) = multi_cpu_increment;
long (*ACE_Atomic_Op<ACE_Thread_Mutex, long>::decrement_fn_) (volatile long *) = multi_cpu_decrement;
long (*ACE_Atomic_Op<ACE_Thread_Mutex, long>::exchange_fn_) (volatile long *, long) = multi_cpu_exchange;
long (*ACE_Atomic_Op<ACE_Thread_Mutex, long>::exchange_add_fn_) (volatile long *, long) = multi_cpu_exchange_add;
void
ACE_Atomic_Op<ACE_Thread_Mutex, long>::init_functions (void)
{
if (ACE_OS::num_processors () == 1)
{
increment_fn_ = single_cpu_increment;
decrement_fn_ = single_cpu_decrement;
exchange_fn_ = single_cpu_exchange;
exchange_add_fn_ = single_cpu_exchange_add;
}
else
{
increment_fn_ = multi_cpu_increment;
decrement_fn_ = multi_cpu_decrement;
exchange_fn_ = multi_cpu_exchange;
exchange_add_fn_ = multi_cpu_exchange_add;
}
}
void
ACE_Atomic_Op<ACE_Thread_Mutex, long>::dump (void) const
{
#if defined (ACE_HAS_DUMP)
ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
#endif /* ACE_HAS_DUMP */
}
long (*ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long>::increment_fn_) (volatile long *) = multi_cpu_increment;
long (*ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long>::decrement_fn_) (volatile long *) = multi_cpu_decrement;
long (*ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long>::exchange_fn_) (volatile long *, long) = multi_cpu_exchange;
long (*ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long>::exchange_add_fn_) (volatile long *, long) = multi_cpu_exchange_add;
void
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long>::init_functions (void)
{
if (ACE_OS::num_processors () == 1)
{
increment_fn_ = single_cpu_increment;
decrement_fn_ = single_cpu_decrement;
exchange_fn_ = single_cpu_exchange;
exchange_add_fn_ = single_cpu_exchange_add;
}
else
{
increment_fn_ = multi_cpu_increment;
decrement_fn_ = multi_cpu_decrement;
exchange_fn_ = multi_cpu_exchange;
exchange_add_fn_ = multi_cpu_exchange_add;
}
}
void
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long>::dump (void) const
{
#if defined (ACE_HAS_DUMP)
ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
#endif /* ACE_HAS_DUMP */
}
ACE_END_VERSIONED_NAMESPACE_DECL
#endif /* ACE_HAS_BUILTIN_ATOMIC_OP */

View File

@@ -0,0 +1,384 @@
// -*- C++ -*-
//=============================================================================
/**
* @file Atomic_Op.h
*
* @author Douglas C. Schmidt <schmidt@uci.edu>
*/
//=============================================================================
#ifndef ACE_ATOMIC_OP_H
#define ACE_ATOMIC_OP_H
#include /**/ "ace/pre.h"
#include /**/ "ace/config-all.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "ace/Thread_Mutex.h"
// Include the templates here.
#include "ace/Atomic_Op_T.h"
// Determine whether builtin atomic op support is
// available on this platform.
#if defined (ACE_HAS_THREADS)
# if defined (WIN32)
# if defined (ACE_HAS_INTRINSIC_INTERLOCKED)
# define ACE_HAS_BUILTIN_ATOMIC_OP
# endif /* ACE_HAS_INTRINSIC_INTERLOCKED */
# if defined (ACE_HAS_INTERLOCKED_EXCHANGEADD)
# define ACE_HAS_BUILTIN_ATOMIC_OP
# else /* ACE_HAS_INTERLOCKED_EXCHANGEADD */
// Inline assembly emulation of InterlockedExchangeAdd
// is currently only implemented for MSVC (x86 only) and Borland.
# if (defined (_MSC_VER) && defined (_M_IX86)) || defined (__BORLANDC__)
# define ACE_HAS_BUILTIN_ATOMIC_OP
# endif /* _MSC_VER || __BORLANDC__ */
# endif /* ACE_HAS_INTERLOCKED_EXCHANGEADD */
# elif defined (ACE_HAS_INTEL_ASSEMBLY)
# define ACE_HAS_BUILTIN_ATOMIC_OP
# elif defined (ACE_HAS_VXATOMICLIB)
# define ACE_HAS_BUILTIN_ATOMIC_OP
# elif defined (ACE_HAS_SOLARIS_ATOMIC_LIB) && !defined (ACE_HAS_BUILTIN_ATOMIC_OP)
# define ACE_HAS_BUILTIN_ATOMIC_OP
# endif /* WIN32 */
#endif /* ACE_HAS_THREADS */
// If we have the GCC Atomic builtin support, use it
#if defined (ACE_HAS_GCC_ATOMIC_BUILTINS) && (ACE_HAS_GCC_ATOMIC_BUILTINS == 1)
# undef ACE_HAS_BUILTIN_ATOMIC_OP
#endif
// Include the templates here.
#include "ace/Atomic_Op_GCC_T.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
#if defined (ACE_HAS_BUILTIN_ATOMIC_OP)
/**
* @brief Specialization of ACE_Atomic_Op for platforms that
* support atomic integer operations.
*
* Specialization of ACE_Atomic_Op for platforms that support atomic
* integer operations.
*/
template<>
class ACE_Export ACE_Atomic_Op<ACE_Thread_Mutex, long>
{
public:
/// Initialize @c value_ to 0.
ACE_Atomic_Op (void);
/// Initialize @c value_ to c.
ACE_Atomic_Op (long c);
/// Manage copying...
ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, long> &c);
/// Atomically pre-increment @c value_.
long operator++ (void);
/// Atomically post-increment @c value_.
long operator++ (int);
/// Atomically increment @c value_ by rhs.
long operator+= (long rhs);
/// Atomically pre-decrement @c value_.
long operator-- (void);
/// Atomically post-decrement @c value_.
long operator-- (int);
/// Atomically decrement @c value_ by rhs.
long operator-= (long rhs);
/// Atomically compare @c value_ with rhs.
bool operator== (long rhs) const;
/// Atomically compare @c value_ with rhs.
bool operator!= (long rhs) const;
/// Atomically check if @c value_ greater than or equal to rhs.
bool operator>= (long rhs) const;
/// Atomically check if @c value_ greater than rhs.
bool operator> (long rhs) const;
/// Atomically check if @c value_ less than or equal to rhs.
bool operator<= (long rhs) const;
/// Atomically check if @c value_ less than rhs.
bool operator< (long rhs) const;
/// Atomically assign rhs to @c value_.
ACE_Atomic_Op<ACE_Thread_Mutex, long> &operator= (long rhs);
/// Atomically assign <rhs> to @c value_.
ACE_Atomic_Op<ACE_Thread_Mutex, long> &operator= (const ACE_Atomic_Op<ACE_Thread_Mutex, long> &rhs);
/// Exchange value with @a newval.
long exchange (long newval);
/// Explicitly return @c value_.
long value (void) const;
/// Dump the state of an object.
void dump (void) const;
/// Explicitly return @c value_ (by reference).
volatile long &value_i (void);
// ACE_ALLOC_HOOK_DECLARE;
// Declare the dynamic allocation hooks.
/// Used during ACE object manager initialization to optimize the fast
/// atomic op implementation according to the number of CPUs.
static void init_functions (void);
private:
/// This function cannot be supported by this template specialization.
/// If you need access to an underlying lock, use the ACE_Atomic_Op_Ex
/// template instead.
ACE_Thread_Mutex &mutex (void);
private:
/// Current object decorated by the atomic op.
volatile long value_;
/// Pointers to selected atomic op implementations.
static long (*increment_fn_) (volatile long *);
static long (*decrement_fn_) (volatile long *);
static long (*exchange_fn_) (volatile long *, long);
static long (*exchange_add_fn_) (volatile long *, long);
};
/**
* @brief Specialization of ACE_Atomic_Op for platforms that
* support atomic integer operations.
*
* Specialization of ACE_Atomic_Op for platforms that support atomic
* integer operations.
*/
template<>
class ACE_Export ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long>
{
public:
/// Initialize @c value_ to 0.
ACE_Atomic_Op (void);
/// Initialize @c value_ to c.
ACE_Atomic_Op (unsigned long c);
/// Manage copying...
ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long> &c);
/// Atomically pre-increment @c value_.
unsigned long operator++ (void);
/// Atomically post-increment @c value_.
unsigned long operator++ (int);
/// Atomically increment @c value_ by rhs.
unsigned long operator+= (unsigned long rhs);
/// Atomically pre-decrement @c value_.
unsigned long operator-- (void);
/// Atomically post-decrement @c value_.
unsigned long operator-- (int);
/// Atomically decrement @c value_ by rhs.
unsigned long operator-= (unsigned long rhs);
/// Atomically compare @c value_ with rhs.
bool operator== (unsigned long rhs) const;
/// Atomically compare @c value_ with rhs.
bool operator!= (unsigned long rhs) const;
/// Atomically check if @c value_ greater than or equal to rhs.
bool operator>= (unsigned long rhs) const;
/// Atomically check if @c value_ greater than rhs.
bool operator> (unsigned long rhs) const;
/// Atomically check if @c value_ less than or equal to rhs.
bool operator<= (unsigned long rhs) const;
/// Atomically check if @c value_ less than rhs.
bool operator< (unsigned long rhs) const;
/// Atomically assign rhs to @c value_.
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long> &operator= (unsigned long rhs);
/// Atomically assign <rhs> to @c value_.
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long> &operator= (const ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long> &rhs);
/// Exchange value with @a newval.
unsigned long exchange (unsigned long newval);
/// Explicitly return @c value_.
unsigned long value (void) const;
/// Dump the state of an object.
void dump (void) const;
/// Explicitly return @c value_ (by reference).
volatile unsigned long &value_i (void);
// ACE_ALLOC_HOOK_DECLARE;
// Declare the dynamic allocation hooks.
/// Used during ACE object manager initialization to optimize the fast
/// atomic op implementation according to the number of CPUs.
static void init_functions (void);
private:
/// This function cannot be supported by this template specialization.
/// If you need access to an underlying lock, use the ACE_Atomic_Op_Ex
/// template instead.
ACE_Thread_Mutex &mutex (void);
private:
/// Current object decorated by the atomic op.
volatile unsigned long value_;
// Pointers to selected atomic op implementations.
static long (*increment_fn_) (volatile long *);
static long (*decrement_fn_) (volatile long *);
static long (*exchange_fn_) (volatile long *, long);
static long (*exchange_add_fn_) (volatile long *, long);
};
#endif /* !ACE_HAS_BUILTIN_ATOMIC_OP */
#if defined (ACE_HAS_GCC_ATOMIC_BUILTINS) && (ACE_HAS_GCC_ATOMIC_BUILTINS == 1)
template<>
class ACE_Export ACE_Atomic_Op<ACE_Thread_Mutex, int>
: public ACE_Atomic_Op_GCC<int>
{
public:
ACE_Atomic_Op (void);
ACE_Atomic_Op (int c);
ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, int> &c);
ACE_Atomic_Op<ACE_Thread_Mutex, int> &operator= (int rhs);
};
template<>
class ACE_Export ACE_Atomic_Op<ACE_Thread_Mutex, unsigned int>
: public ACE_Atomic_Op_GCC<unsigned int>
{
public:
ACE_Atomic_Op (void);
ACE_Atomic_Op (unsigned int c);
ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, unsigned> &c);
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned int> &operator= (unsigned int rhs);
};
// If we have built in atomic op, use that, the assignment operator
// is faster for a long/unsinged long
template<>
class ACE_Export ACE_Atomic_Op<ACE_Thread_Mutex, long>
: public ACE_Atomic_Op_GCC<long>
{
public:
ACE_Atomic_Op (void);
ACE_Atomic_Op (long c);
ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, long> &c);
ACE_Atomic_Op<ACE_Thread_Mutex, long> &operator= (long rhs);
};
template<>
class ACE_Export ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long>
: public ACE_Atomic_Op_GCC<unsigned long>
{
public:
ACE_Atomic_Op (void);
ACE_Atomic_Op (unsigned long c);
ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long> &c);
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long> &operator= (unsigned long rhs);
};
// The long long intrinsics are not available on PPC
#if !defined (__powerpc__)
template<>
class ACE_Export ACE_Atomic_Op<ACE_Thread_Mutex, long long>
: public ACE_Atomic_Op_GCC<long long>
{
public:
ACE_Atomic_Op (void);
ACE_Atomic_Op (long long c);
ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, long long> &c);
ACE_Atomic_Op<ACE_Thread_Mutex, long long> &operator= (long long rhs);
};
template<>
class ACE_Export ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long long>
: public ACE_Atomic_Op_GCC<unsigned long long>
{
public:
ACE_Atomic_Op (void);
ACE_Atomic_Op (unsigned long long c);
ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long long> &c);
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long long> &operator= (unsigned long long rhs);
};
#endif /* !__powerpc__ */
#if !defined (ACE_LACKS_GCC_ATOMIC_BUILTINS_2)
template<>
class ACE_Export ACE_Atomic_Op<ACE_Thread_Mutex, short>
: public ACE_Atomic_Op_GCC<short>
{
public:
ACE_Atomic_Op (void);
ACE_Atomic_Op (short c);
ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, short> &c);
ACE_Atomic_Op<ACE_Thread_Mutex, short> &operator= (short rhs);
};
template<>
class ACE_Export ACE_Atomic_Op<ACE_Thread_Mutex, unsigned short>
: public ACE_Atomic_Op_GCC<unsigned short>
{
public:
ACE_Atomic_Op (void);
ACE_Atomic_Op (unsigned short c);
ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, unsigned short> &c);
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned short> &operator= (unsigned short rhs);
};
#endif
#if !defined (ACE_LACKS_GCC_ATOMIC_BUILTINS_1)
template<>
class ACE_Export ACE_Atomic_Op<ACE_Thread_Mutex, bool>
: public ACE_Atomic_Op_GCC<bool>
{
public:
ACE_Atomic_Op (void);
ACE_Atomic_Op (bool c);
ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, bool> &c);
ACE_Atomic_Op<ACE_Thread_Mutex, bool> &operator= (bool rhs);
};
#endif
#endif /* ACE_HAS_BUILTIN_ATOMIC_OP */
ACE_END_VERSIONED_NAMESPACE_DECL
#if defined (__ACE_INLINE__)
#include "ace/Atomic_Op.inl"
#endif /* __ACE_INLINE__ */
#include /**/ "ace/post.h"
#endif /*ACE_ATOMIC_OP_H*/

View File

@@ -0,0 +1,666 @@
// -*- C++ -*-
#if defined (ACE_HAS_INTRINSIC_INTERLOCKED)
# include "ace/os_include/os_intrin.h"
# pragma intrinsic (_InterlockedExchange, _InterlockedExchangeAdd, _InterlockedIncrement, _InterlockedDecrement)
#endif /* ACE_HAS_INTRINSIC_INTERLOCKED */
#if defined (ACE_HAS_VXATOMICLIB)
# include <vxAtomicLib.h>
#endif
#if defined (ACE_HAS_SOLARIS_ATOMIC_LIB)
# include <atomic.h>
#endif
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
#if defined (ACE_HAS_BUILTIN_ATOMIC_OP)
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, long>::ACE_Atomic_Op (void)
: value_ (0)
{
}
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, long>::ACE_Atomic_Op (long c)
: value_ (c)
{
}
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, long>::ACE_Atomic_Op (
const ACE_Atomic_Op<ACE_Thread_Mutex, long> &rhs)
: value_ (rhs.value_)
{
}
ACE_INLINE long
ACE_Atomic_Op<ACE_Thread_Mutex, long>::operator++ (void)
{
#if defined (ACE_HAS_INTRINSIC_INTERLOCKED)
return ::_InterlockedIncrement (const_cast<long *> (&this->value_));
#elif defined (WIN32)
return ::InterlockedIncrement (const_cast<long *> (&this->value_));
#elif defined (ACE_HAS_VXATOMICLIB)
return ::vxAtomicInc (reinterpret_cast <atomic_t*>(const_cast<long *> (&this->value_))) + 1;
#elif defined (ACE_HAS_SOLARIS_ATOMIC_LIB)
return ::atomic_inc_ulong_nv (reinterpret_cast<volatile unsigned long*>(&this->value_));
#else /* WIN32 */
return (*increment_fn_) (&this->value_);
#endif /* WIN32 */
}
ACE_INLINE long
ACE_Atomic_Op<ACE_Thread_Mutex, long>::operator++ (int)
{
return ++*this - 1;
}
ACE_INLINE long
ACE_Atomic_Op<ACE_Thread_Mutex, long>::operator-- (void)
{
#if defined (ACE_HAS_INTRINSIC_INTERLOCKED)
return ::_InterlockedDecrement (const_cast<long *> (&this->value_));
#elif defined (WIN32)
return ::InterlockedDecrement (const_cast<long *> (&this->value_));
#elif defined (ACE_HAS_VXATOMICLIB)
return ::vxAtomicDec (reinterpret_cast <atomic_t*>(const_cast<long *> (&this->value_))) - 1;
#elif defined (ACE_HAS_SOLARIS_ATOMIC_LIB)
return ::atomic_dec_ulong_nv (reinterpret_cast<volatile unsigned long*>(&this->value_));
#else /* WIN32 */
return (*decrement_fn_) (&this->value_);
#endif /* WIN32 */
}
ACE_INLINE long
ACE_Atomic_Op<ACE_Thread_Mutex, long>::operator-- (int)
{
return --*this + 1;
}
ACE_INLINE long
ACE_Atomic_Op<ACE_Thread_Mutex, long>::operator+= (long rhs)
{
#if defined (ACE_HAS_INTRINSIC_INTERLOCKED)
return ::_InterlockedExchangeAdd (const_cast<long *> (&this->value_),
rhs) + rhs;
#elif defined (WIN32) && defined (ACE_HAS_INTERLOCKED_EXCHANGEADD)
return ::InterlockedExchangeAdd (const_cast<long *> (&this->value_),
rhs) + rhs;
#elif defined (ACE_HAS_VXATOMICLIB)
return ::vxAtomicAdd (reinterpret_cast <atomic_t*>(const_cast<long *> (&this->value_)), rhs) + rhs;
#elif defined (ACE_HAS_SOLARIS_ATOMIC_LIB)
return ::atomic_add_long_nv (reinterpret_cast<volatile unsigned long*>(&this->value_), rhs);
#else /* WIN32 && ACE_HAS_INTERLOCKED_EXCHANGEADD */
return (*exchange_add_fn_) (&this->value_, rhs) + rhs;
#endif /* WIN32 && ACE_HAS_INTERLOCKED_EXCHANGEADD */
}
ACE_INLINE long
ACE_Atomic_Op<ACE_Thread_Mutex, long>::operator-= (long rhs)
{
#if defined (ACE_HAS_INTRINSIC_INTERLOCKED)
return ::_InterlockedExchangeAdd (const_cast<long *> (&this->value_),
-rhs) - rhs;
#elif defined (WIN32) && defined (ACE_HAS_INTERLOCKED_EXCHANGEADD)
return ::InterlockedExchangeAdd (const_cast<long *> (&this->value_),
-rhs) - rhs;
#elif defined (ACE_HAS_VXATOMICLIB)
return ::vxAtomicSub (reinterpret_cast <atomic_t*>(const_cast<long *> (&this->value_)), rhs) - rhs;
#elif defined (ACE_HAS_SOLARIS_ATOMIC_LIB)
return ::atomic_add_long_nv (reinterpret_cast<volatile unsigned long*>(&this->value_), -rhs);
#else /* WIN32 && ACE_HAS_INTERLOCKED_EXCHANGEADD */
return (*exchange_add_fn_) (&this->value_, -rhs) - rhs;
#endif /* WIN32 && ACE_HAS_INTERLOCKED_EXCHANGEADD */
}
ACE_INLINE bool
ACE_Atomic_Op<ACE_Thread_Mutex, long>::operator== (long rhs) const
{
return (this->value_ == rhs);
}
ACE_INLINE bool
ACE_Atomic_Op<ACE_Thread_Mutex, long>::operator!= (long rhs) const
{
return (this->value_ != rhs);
}
ACE_INLINE bool
ACE_Atomic_Op<ACE_Thread_Mutex, long>::operator>= (long rhs) const
{
return (this->value_ >= rhs);
}
ACE_INLINE bool
ACE_Atomic_Op<ACE_Thread_Mutex, long>::operator> (long rhs) const
{
return (this->value_ > rhs);
}
ACE_INLINE bool
ACE_Atomic_Op<ACE_Thread_Mutex, long>::operator<= (long rhs) const
{
return (this->value_ <= rhs);
}
ACE_INLINE bool
ACE_Atomic_Op<ACE_Thread_Mutex, long>::operator< (long rhs) const
{
return (this->value_ < rhs);
}
ACE_INLINE ACE_Atomic_Op<ACE_Thread_Mutex, long> &
ACE_Atomic_Op<ACE_Thread_Mutex, long>::operator= (long rhs)
{
#if defined (ACE_HAS_INTRINSIC_INTERLOCKED)
::_InterlockedExchange (const_cast<long *> (&this->value_), rhs);
#elif defined (WIN32)
::InterlockedExchange (const_cast<long *> (&this->value_), rhs);
#elif defined (ACE_HAS_VXATOMICLIB)
::vxAtomicSet (reinterpret_cast <atomic_t*>(const_cast<long *> (&this->value_)), rhs);
#elif defined (ACE_HAS_SOLARIS_ATOMIC_LIB)
::atomic_swap_ulong (reinterpret_cast<volatile unsigned long*>(&this->value_), rhs);
#else /* WIN32 */
(*exchange_fn_) (&this->value_, rhs);
#endif /* WIN32 */
return *this;
}
ACE_INLINE ACE_Atomic_Op<ACE_Thread_Mutex, long> &
ACE_Atomic_Op<ACE_Thread_Mutex, long>::operator= (
const ACE_Atomic_Op<ACE_Thread_Mutex, long> &rhs)
{
#if defined (ACE_HAS_INTRINSIC_INTERLOCKED)
::_InterlockedExchange (const_cast<long *> (&this->value_), rhs.value_);
#elif defined (WIN32)
::InterlockedExchange (const_cast<long *> (&this->value_), rhs.value_);
#elif defined (ACE_HAS_VXATOMICLIB)
::vxAtomicSet (reinterpret_cast <atomic_t*>(const_cast<long *> (&this->value_)), rhs.value_);
#elif defined (ACE_HAS_SOLARIS_ATOMIC_LIB)
::atomic_swap_ulong (reinterpret_cast<volatile unsigned long*>(&this->value_), rhs.value_);
#else /* WIN32 */
(*exchange_fn_) (&this->value_, rhs.value_);
#endif /* WIN32 */
return *this;
}
ACE_INLINE long
ACE_Atomic_Op<ACE_Thread_Mutex, long>::exchange (long newval)
{
#if defined (ACE_HAS_INTRINSIC_INTERLOCKED)
return ::_InterlockedExchange (const_cast<long *> (&this->value_), newval);
#elif defined (WIN32)
return ::InterlockedExchange (const_cast<long *> (&this->value_), newval);
#elif defined (ACE_HAS_VXATOMICLIB)
return ::vxAtomicSet (reinterpret_cast <atomic_t*>(const_cast<long *> (&this->value_)), newval);
#elif defined (ACE_HAS_SOLARIS_ATOMIC_LIB)
return ::atomic_swap_ulong (reinterpret_cast<volatile unsigned long*>(&this->value_), newval);
#else /* WIN32 */
return (*exchange_fn_) (&this->value_, newval);
#endif /* WIN32 */
}
ACE_INLINE long
ACE_Atomic_Op<ACE_Thread_Mutex, long>::value (void) const
{
return this->value_;
}
ACE_INLINE volatile long &
ACE_Atomic_Op<ACE_Thread_Mutex, long>::value_i (void)
{
return this->value_;
}
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long>::ACE_Atomic_Op (void)
: value_ (0)
{
}
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long>::ACE_Atomic_Op (unsigned long c)
: value_ (c)
{
}
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long>::ACE_Atomic_Op (
const ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long> &rhs)
: value_ (rhs.value_)
{
}
ACE_INLINE unsigned long
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long>::operator++ (void)
{
#if defined (ACE_HAS_INTRINSIC_INTERLOCKED)
return static_cast<unsigned long> (::_InterlockedIncrement (const_cast<long *> (reinterpret_cast<volatile long *>(&this->value_))));
#elif defined (WIN32)
return static_cast<unsigned long> (::InterlockedIncrement (const_cast<long *> (reinterpret_cast<volatile long *>(&this->value_))));
#elif defined (ACE_HAS_VXATOMICLIB)
return static_cast<unsigned long> (::vxAtomicInc (reinterpret_cast <atomic_t*>(const_cast<long *> (reinterpret_cast<volatile long *>(&this->value_))))) + 1;
#elif defined (ACE_HAS_SOLARIS_ATOMIC_LIB)
return ::atomic_inc_ulong_nv (&this->value_);
#else /* WIN32 */
return static_cast<unsigned long> ((*increment_fn_) (reinterpret_cast<volatile long *> (&this->value_)));
#endif /* WIN32 */
}
ACE_INLINE unsigned long
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long>::operator++ (int)
{
return ++*this - 1;
}
ACE_INLINE unsigned long
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long>::operator-- (void)
{
#if defined (ACE_HAS_INTRINSIC_INTERLOCKED)
return static_cast<unsigned long> (::_InterlockedDecrement (const_cast<long *> (reinterpret_cast<volatile long *>(&this->value_))));
#elif defined (WIN32)
return static_cast<unsigned long> (::InterlockedDecrement (const_cast<long *> (reinterpret_cast<volatile long *>(&this->value_))));
#elif defined (ACE_HAS_VXATOMICLIB)
return static_cast<unsigned long> (::vxAtomicDec (reinterpret_cast <atomic_t*>(const_cast<long *> (reinterpret_cast<volatile long *>(&this->value_))))) - 1;
#elif defined (ACE_HAS_SOLARIS_ATOMIC_LIB)
return ::atomic_dec_ulong_nv (&this->value_);
#else /* WIN32 */
return static_cast<unsigned long> ((*decrement_fn_) (reinterpret_cast<volatile long *> (&this->value_)));
#endif /* WIN32 */
}
ACE_INLINE unsigned long
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long>::operator-- (int)
{
return --*this + 1;
}
ACE_INLINE unsigned long
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long>::operator+= (unsigned long rhs)
{
#if defined (ACE_HAS_INTRINSIC_INTERLOCKED)
return static_cast<unsigned long> (::_InterlockedExchangeAdd (const_cast<long *> (reinterpret_cast <volatile long *>(&this->value_)),
rhs)) + rhs;
#elif defined (WIN32) && defined (ACE_HAS_INTERLOCKED_EXCHANGEADD)
return static_cast<unsigned long> (::InterlockedExchangeAdd (const_cast<long *> (reinterpret_cast <volatile long *>(&this->value_)),
rhs)) + rhs;
#elif defined (ACE_HAS_VXATOMICLIB)
return static_cast<unsigned long> (::vxAtomicAdd (reinterpret_cast <atomic_t*>(const_cast<long *> (reinterpret_cast<volatile long *>(&this->value_))), rhs)) + rhs;
#elif defined (ACE_HAS_SOLARIS_ATOMIC_LIB)
return ::atomic_add_long_nv (&this->value_, rhs);
#else /* WIN32 && ACE_HAS_INTERLOCKED_EXCHANGEADD */
return static_cast<unsigned long> ((*exchange_add_fn_) (reinterpret_cast<volatile long *> (&this->value_), rhs)) + rhs;
#endif /* WIN32 && ACE_HAS_INTERLOCKED_EXCHANGEADD */
}
ACE_INLINE unsigned long
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long>::operator-= (unsigned long rhs)
{
#if defined (ACE_HAS_INTRINSIC_INTERLOCKED)
return static_cast<unsigned long> (::_InterlockedExchangeAdd (const_cast<long *> (reinterpret_cast<volatile long *>(&this->value_)),
-static_cast<long>(rhs))) - rhs;
#elif defined (WIN32) && defined (ACE_HAS_INTERLOCKED_EXCHANGEADD)
return static_cast<unsigned long> (::InterlockedExchangeAdd (const_cast<long *> (reinterpret_cast<volatile long *>(&this->value_)),
-static_cast<long>(rhs))) - rhs;
#elif defined (ACE_HAS_VXATOMICLIB)
return static_cast<unsigned long> (::vxAtomicSub (reinterpret_cast <atomic_t*>(const_cast<long *> (reinterpret_cast<volatile long *>(&this->value_))), rhs)) - rhs;
#elif defined (ACE_HAS_SOLARIS_ATOMIC_LIB)
return ::atomic_add_long_nv (&this->value_, -rhs);
#else /* WIN32 && ACE_HAS_INTERLOCKED_EXCHANGEADD */
long l_rhs = static_cast<long> (rhs);
return static_cast<unsigned long> ((*exchange_add_fn_) (reinterpret_cast<volatile long *> (&this->value_), -l_rhs)) - rhs;
#endif /* WIN32 && ACE_HAS_INTERLOCKED_EXCHANGEADD */
}
ACE_INLINE bool
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long>::operator== (unsigned long rhs) const
{
return (this->value_ == rhs);
}
ACE_INLINE bool
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long>::operator!= (unsigned long rhs) const
{
return (this->value_ != rhs);
}
ACE_INLINE bool
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long>::operator>= (unsigned long rhs) const
{
return (this->value_ >= rhs);
}
ACE_INLINE bool
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long>::operator> (unsigned long rhs) const
{
return (this->value_ > rhs);
}
ACE_INLINE bool
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long>::operator<= (unsigned long rhs) const
{
return (this->value_ <= rhs);
}
ACE_INLINE bool
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long>::operator< (unsigned long rhs) const
{
return (this->value_ < rhs);
}
ACE_INLINE ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long> &
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long>::operator= (unsigned long rhs)
{
#if defined (ACE_HAS_INTRINSIC_INTERLOCKED)
::_InterlockedExchange (const_cast<long *> (reinterpret_cast<volatile long*> (&this->value_)), rhs);
#elif defined (WIN32)
::InterlockedExchange (const_cast<long *> (reinterpret_cast<volatile long*> (&this->value_)), rhs);
#elif defined (ACE_HAS_VXATOMICLIB)
::vxAtomicSet (reinterpret_cast <atomic_t*>(const_cast<long *> (reinterpret_cast<volatile long*> (&this->value_))), rhs);
#elif defined (ACE_HAS_SOLARIS_ATOMIC_LIB)
::atomic_swap_ulong (&this->value_, rhs);
#else /* WIN32 */
(*exchange_fn_) (reinterpret_cast<volatile long *> (&this->value_), rhs);
#endif /* WIN32 */
return *this;
}
ACE_INLINE ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long> &
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long>::operator= (
const ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long> &rhs)
{
#if defined (ACE_HAS_INTRINSIC_INTERLOCKED)
::_InterlockedExchange (const_cast<long *> (reinterpret_cast<volatile long*> (&this->value_)), rhs.value_);
#elif defined (WIN32)
::InterlockedExchange (const_cast<long *> (reinterpret_cast<volatile long*> (&this->value_)), rhs.value_);
#elif defined (ACE_HAS_VXATOMICLIB)
::vxAtomicSet (reinterpret_cast <atomic_t*>(const_cast<long *> (reinterpret_cast<volatile long*> (&this->value_))), rhs.value_);
#elif defined (ACE_HAS_SOLARIS_ATOMIC_LIB)
::atomic_swap_ulong (&this->value_, rhs.value_);
#else /* WIN32 */
(*exchange_fn_) (reinterpret_cast<volatile long *> (&this->value_), rhs.value_);
#endif /* WIN32 */
return *this;
}
ACE_INLINE unsigned long
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long>::exchange (unsigned long newval)
{
#if defined (ACE_HAS_INTRINSIC_INTERLOCKED)
return ::_InterlockedExchange (const_cast<long *> (reinterpret_cast<volatile long*> (&this->value_)), newval);
#elif defined (WIN32)
return ::InterlockedExchange (const_cast<long *> (reinterpret_cast<volatile long*> (&this->value_)), newval);
#elif defined (ACE_HAS_VXATOMICLIB)
return ::vxAtomicSet (reinterpret_cast <atomic_t*>(const_cast<long *> (reinterpret_cast<volatile long*> (&this->value_))), newval);
#elif defined (ACE_HAS_SOLARIS_ATOMIC_LIB)
return ::atomic_swap_ulong (&this->value_, newval);
#else /* WIN32 */
return (*exchange_fn_) (reinterpret_cast<volatile long *> (&this->value_), newval);
#endif /* WIN32 */
}
ACE_INLINE unsigned long
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long>::value (void) const
{
return this->value_;
}
ACE_INLINE volatile unsigned long &
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long>::value_i (void)
{
return this->value_;
}
#endif /* ACE_HAS_BUILTIN_ATOMIC_OP */
#if defined (ACE_HAS_GCC_ATOMIC_BUILTINS) && (ACE_HAS_GCC_ATOMIC_BUILTINS == 1)
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, int>::ACE_Atomic_Op (void) :
ACE_Atomic_Op_GCC<int> ()
{
}
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, int>::ACE_Atomic_Op (int c) :
ACE_Atomic_Op_GCC<int>(c)
{
}
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, int>::ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, int> &c) :
ACE_Atomic_Op_GCC<int>(c)
{
}
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, int>&
ACE_Atomic_Op<ACE_Thread_Mutex, int>::operator= (int rhs)
{
ACE_Atomic_Op_GCC<int>::operator= (rhs);
return *this;
}
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned int>::ACE_Atomic_Op (void) :
ACE_Atomic_Op_GCC<unsigned int>()
{
}
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned int>::ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, unsigned int> &c) :
ACE_Atomic_Op_GCC<unsigned int>(c)
{
}
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned int>::ACE_Atomic_Op (unsigned int c) :
ACE_Atomic_Op_GCC<unsigned int>(c)
{
}
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned int>&
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned int>::operator= (unsigned int rhs)
{
ACE_Atomic_Op_GCC<unsigned int>::operator= (rhs);
return *this;
}
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, long>::ACE_Atomic_Op (void) :
ACE_Atomic_Op_GCC<long>()
{
}
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, long>::ACE_Atomic_Op (long c) :
ACE_Atomic_Op_GCC<long>(c)
{
}
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, long>::ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, long> &c) :
ACE_Atomic_Op_GCC<long>(c)
{
}
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, long>&
ACE_Atomic_Op<ACE_Thread_Mutex, long>::operator= (long rhs)
{
ACE_Atomic_Op_GCC<long>::operator= (rhs);
return *this;
}
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long>::ACE_Atomic_Op (void) :
ACE_Atomic_Op_GCC<unsigned long> ()
{
}
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long>::ACE_Atomic_Op (unsigned long c) :
ACE_Atomic_Op_GCC<unsigned long>(c)
{
}
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long>::ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long> &c) :
ACE_Atomic_Op_GCC<unsigned long>(c)
{
}
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long>&
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long>::operator= (unsigned long rhs)
{
ACE_Atomic_Op_GCC<unsigned long>::operator= (rhs);
return *this;
}
// The long long intrinsics are not available on PPC
#if !defined (__powerpc__)
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, long long>::ACE_Atomic_Op (void) :
ACE_Atomic_Op_GCC<long long>()
{
}
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, long long>::ACE_Atomic_Op (long long c) :
ACE_Atomic_Op_GCC<long long>(c)
{
}
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, long long>::ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, long long> &c) :
ACE_Atomic_Op_GCC<long long>(c)
{
}
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, long long>&
ACE_Atomic_Op<ACE_Thread_Mutex, long long>::operator= (long long rhs)
{
ACE_Atomic_Op_GCC<long long>::operator= (rhs);
return *this;
}
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long long>::ACE_Atomic_Op (void) :
ACE_Atomic_Op_GCC<unsigned long long> ()
{
}
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long long>::ACE_Atomic_Op (unsigned long long c) :
ACE_Atomic_Op_GCC<unsigned long long>(c)
{
}
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long long>::ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long long> &c) :
ACE_Atomic_Op_GCC<unsigned long long>(c)
{
}
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long long>&
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long long>::operator= (unsigned long long rhs)
{
ACE_Atomic_Op_GCC<unsigned long long>::operator= (rhs);
return *this;
}
#endif /* !__powerpc__ */
#if !defined (ACE_LACKS_GCC_ATOMIC_BUILTINS_2)
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, short>::ACE_Atomic_Op (void) :
ACE_Atomic_Op_GCC<short>()
{
}
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, short>::ACE_Atomic_Op (short c) :
ACE_Atomic_Op_GCC<short>(c)
{
}
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, short>::ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, short> &c) :
ACE_Atomic_Op_GCC<short>(c)
{
}
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, short>&
ACE_Atomic_Op<ACE_Thread_Mutex, short>::operator= (short rhs)
{
ACE_Atomic_Op_GCC<short>::operator= (rhs);
return *this;
}
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned short>::ACE_Atomic_Op (void) :
ACE_Atomic_Op_GCC<unsigned short> ()
{
}
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned short>::ACE_Atomic_Op (unsigned short c) :
ACE_Atomic_Op_GCC<unsigned short>(c)
{
}
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned short>::ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, unsigned short> &c) :
ACE_Atomic_Op_GCC<unsigned short>(c)
{
}
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned short>&
ACE_Atomic_Op<ACE_Thread_Mutex, unsigned short>::operator= (unsigned short rhs)
{
ACE_Atomic_Op_GCC<unsigned short>::operator= (rhs);
return *this;
}
#endif
#if !defined (ACE_LACKS_GCC_ATOMIC_BUILTINS_1)
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, bool>::ACE_Atomic_Op (void) :
ACE_Atomic_Op_GCC<bool> ()
{
}
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, bool>::ACE_Atomic_Op (bool c) :
ACE_Atomic_Op_GCC<bool>(c)
{
}
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, bool>::ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, bool> &c) :
ACE_Atomic_Op_GCC<bool>(c)
{
}
ACE_INLINE
ACE_Atomic_Op<ACE_Thread_Mutex, bool>&
ACE_Atomic_Op<ACE_Thread_Mutex, bool>::operator= (bool rhs)
{
ACE_Atomic_Op_GCC<bool>::operator= (rhs);
return *this;
}
#endif
#endif /* ACE_HAS_GCC_ATOMIC_BUILTINS==1 */
ACE_END_VERSIONED_NAMESPACE_DECL

View File

@@ -0,0 +1,23 @@
#include "ace/OS_NS_unistd.h"
#if defined (ACE_HAS_GCC_ATOMIC_BUILTINS) && (ACE_HAS_GCC_ATOMIC_BUILTINS == 1)
#if !defined (__ACE_INLINE__)
#include "ace/Atomic_Op_GCC_T.inl"
#endif /* __ACE_INLINE__ */
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
template <typename T>
void
ACE_Atomic_Op_GCC<T>::dump (void) const
{
#if defined (ACE_HAS_DUMP)
ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
#endif /* ACE_HAS_DUMP */
}
ACE_END_VERSIONED_NAMESPACE_DECL
#endif /* ACE_HAS_GCC_ATOMIC_BUILTINS */

View File

@@ -0,0 +1,137 @@
// -*- C++ -*-
//=============================================================================
/**
* @file Atomic_Op_GCC_T.h
*
* @author Johnny Willemsen <jwillemsen@remedy.nl
*/
//=============================================================================
#ifndef ACE_ATOMIC_OP_GCC_T_H
#define ACE_ATOMIC_OP_GCC_T_H
#include /**/ "ace/pre.h"
#include /**/ "ace/config-all.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "ace/Thread_Mutex.h"
#include "ace/ACE_export.h"
#if defined (ACE_HAS_GCC_ATOMIC_BUILTINS) && (ACE_HAS_GCC_ATOMIC_BUILTINS == 1)
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
/**
* @brief Specialization of ACE_Atomic_Op for platforms that
* support atomic integer operations.
*
* Specialization of ACE_Atomic_Op for platforms that support atomic
* integer operations.
*/
template<typename T>
class ACE_Export ACE_Atomic_Op_GCC
{
public:
/// Atomically pre-increment @c value_.
T operator++ (void);
/// Atomically post-increment @c value_.
T operator++ (int);
/// Atomically increment @c value_ by rhs.
T operator+= (T rhs);
/// Atomically pre-decrement @c value_.
T operator-- (void);
/// Atomically post-decrement @c value_.
T operator-- (int);
/// Atomically decrement @c value_ by rhs.
T operator-= (T rhs);
/// Atomically compare @c value_ with rhs.
bool operator== (T rhs) const;
/// Atomically compare @c value_ with rhs.
bool operator!= (T rhs) const;
/// Atomically check if @c value_ greater than or equal to rhs.
bool operator>= (T rhs) const;
/// Atomically check if @c value_ greater than rhs.
bool operator> (T rhs) const;
/// Atomically check if @c value_ less than or equal to rhs.
bool operator<= (T rhs) const;
/// Atomically check if @c value_ less than rhs.
bool operator< (T rhs) const;
/// Exchange value with @a newval.
T exchange (T newval);
/// Explicitly return @c value_.
T value (void) const;
/// Dump the state of an object.
void dump (void) const;
/// Explicitly return @c value_ (by reference).
volatile T &value_i (void);
// ACE_ALLOC_HOOK_DECLARE;
// Declare the dynamic allocation hooks.
protected:
/// Atomically assign rhs to @c value_.
ACE_Atomic_Op_GCC<T> &operator= (T rhs);
/// Atomically assign <rhs> to @c value_.
ACE_Atomic_Op_GCC<T> &operator= (const ACE_Atomic_Op_GCC<T> &rhs);
/// Initialize @c value_ to 0.
ACE_Atomic_Op_GCC (void);
/// Initialize @c value_ to c.
ACE_Atomic_Op_GCC (T c);
/// Manage copying...
ACE_Atomic_Op_GCC (const ACE_Atomic_Op_GCC<T> &c);
private:
// This function cannot be supported by this template specialization.
// If you need access to an underlying lock, use the ACE_Atomic_Op_Ex
// template instead.
ACE_Thread_Mutex &mutex (void);
private:
/// Current object decorated by the atomic op.
volatile T value_;
};
ACE_END_VERSIONED_NAMESPACE_DECL
#if defined (__ACE_INLINE__)
#include "ace/Atomic_Op_GCC_T.inl"
#endif /* __ACE_INLINE__ */
#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
#include "ace/Atomic_Op_GCC_T.cpp"
#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
#pragma implementation ("Atomic_Op_GCC_T.cpp")
#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
#endif /* ACE_HAS_GCC_ATOMIC_BUILTINS */
#include /**/ "ace/post.h"
#endif /*ACE_ATOMIC_OP_GCC_T_H*/

View File

@@ -0,0 +1,152 @@
// -*- C++ -*-
#if defined (ACE_HAS_GCC_ATOMIC_BUILTINS) && (ACE_HAS_GCC_ATOMIC_BUILTINS == 1)
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
template <typename T>
ACE_INLINE
ACE_Atomic_Op_GCC<T>::ACE_Atomic_Op_GCC (void)
: value_ (0)
{
}
template <typename T>
ACE_INLINE
ACE_Atomic_Op_GCC<T>::ACE_Atomic_Op_GCC (T c)
: value_ (c)
{
}
template <typename T>
ACE_INLINE
ACE_Atomic_Op_GCC<T>::ACE_Atomic_Op_GCC (
const ACE_Atomic_Op_GCC<T> &rhs)
: value_ (rhs.value_)
{
}
template <typename T>
ACE_INLINE T
ACE_Atomic_Op_GCC<T>::operator++ (void)
{
return __sync_add_and_fetch (&this->value_, 1);
}
template <typename T>
ACE_INLINE T
ACE_Atomic_Op_GCC<T>::operator++ (int)
{
return __sync_fetch_and_add (&this->value_, 1);
}
template <typename T>
ACE_INLINE T
ACE_Atomic_Op_GCC<T>::operator-- (void)
{
return __sync_sub_and_fetch (&this->value_, 1);
}
template <typename T>
ACE_INLINE T
ACE_Atomic_Op_GCC<T>::operator-- (int)
{
return __sync_fetch_and_sub (&this->value_, 1);
}
template <typename T>
ACE_INLINE T
ACE_Atomic_Op_GCC<T>::operator+= (T rhs)
{
return __sync_add_and_fetch (&this->value_, rhs);
}
template <typename T>
ACE_INLINE T
ACE_Atomic_Op_GCC<T>::operator-= (T rhs)
{
return __sync_sub_and_fetch (&this->value_, rhs);
}
template <typename T>
ACE_INLINE bool
ACE_Atomic_Op_GCC<T>::operator== (T rhs) const
{
return (this->value_ == rhs);
}
template <typename T>
ACE_INLINE bool
ACE_Atomic_Op_GCC<T>::operator!= (T rhs) const
{
return (this->value_ != rhs);
}
template <typename T>
ACE_INLINE bool
ACE_Atomic_Op_GCC<T>::operator>= (T rhs) const
{
return (this->value_ >= rhs);
}
template <typename T>
ACE_INLINE bool
ACE_Atomic_Op_GCC<T>::operator> (T rhs) const
{
return (this->value_ > rhs);
}
template <typename T>
ACE_INLINE bool
ACE_Atomic_Op_GCC<T>::operator<= (T rhs) const
{
return (this->value_ <= rhs);
}
template <typename T>
ACE_INLINE bool
ACE_Atomic_Op_GCC<T>::operator< (T rhs) const
{
return (this->value_ < rhs);
}
template <typename T>
ACE_INLINE ACE_Atomic_Op_GCC<T> &
ACE_Atomic_Op_GCC<T>::operator= (T rhs)
{
(void) __sync_lock_test_and_set (&this->value_, rhs);
return *this;
}
template <typename T>
ACE_INLINE ACE_Atomic_Op_GCC<T> &
ACE_Atomic_Op_GCC<T>::operator= (
const ACE_Atomic_Op_GCC<T> &rhs)
{
(void) __sync_lock_test_and_set (&this->value_, rhs.value_);
return *this;
}
template <typename T>
ACE_INLINE T
ACE_Atomic_Op_GCC<T>::exchange (T newval)
{
return __sync_val_compare_and_swap (&this->value_, this->value_, newval);
}
template <typename T>
ACE_INLINE T
ACE_Atomic_Op_GCC<T>::value (void) const
{
return this->value_;
}
template <typename T>
ACE_INLINE volatile T &
ACE_Atomic_Op_GCC<T>::value_i (void)
{
return this->value_;
}
ACE_END_VERSIONED_NAMESPACE_DECL
#endif /* ACE_HAS_GCC_ATOMIC_BUILTINS */

View File

@@ -0,0 +1,187 @@
/*
*
* This is a C file for a reason. The Sun C++ compiler does not accept
* inline assembler.
*
* Portions of this code are based on atomic operations found in the
* linux kernel source code.
*/
#if defined (ACE_INCLUDE_ATOMIC_OP_SPARC)
#if defined(__i386) && defined(__SUNPRO_C)
static void
__sunpro_asm_code() {
__asm("\n\
.globl ace_atomic_add_long \n\
.type ace_atomic_add_long,@function \n\
.align 4 \n\
ace_atomic_add_long: \n\
movl 0x00000004(%esp), %edx \n\
movl 0x00000008(%esp), %eax \n\
lock; xadd %eax, (%edx) \n\
addl 0x00000008(%esp), %eax \n\
ret \n\
");
__asm("\n\
.globl ace_atomic_swap_long \n\
.type ace_atomic_swap_long,@function \n\
.align 4 \n\
ace_atomic_swap_long: \n\
movl 0x00000004(%esp), %edx \n\
movl 0x00000008(%esp), %eax \n\
xchg %eax, (%edx) \n\
ret \n\
");
__asm("\n\
.globl ace_atomic_swap_add_long \n\
.type ace_atomic_swap_add_long,@function \n\
.align 4 \n\
ace_atomic_swap_add_long: \n\
movl 0x00000004(%esp), %edx \n\
movl 0x00000008(%esp), %eax \n\
lock; xadd %eax, (%edx) \n\
ret \n\
");
}
#elif defined(__x86_64) && defined(__SUNPRO_C)
static void
__sunpro_asm_code() {
__asm("\n\
.globl ace_atomic_add_long \n\
.type ace_atomic_add_long,@function \n\
.align 16 \n\
ace_atomic_add_long: \n\
movq %rsi, %rax \n\
lock; xaddq %rax, (%rdi) \n\
addq %rsi, %rax \n\
ret \n\
");
__asm("\n\
.globl ace_atomic_swap_long \n\
.type ace_atomic_swap_long,@function \n\
.align 16 \n\
ace_atomic_swap_long: \n\
xchgq %rsi, (%rdi) \n\
movq %rsi, %rax \n\
ret \n\
");
__asm("\n\
.globl ace_atomic_swap_add_long \n\
.type ace_atomic_swap_add_long,@function \n\
.align 16 \n\
ace_atomic_swap_add_long: \n\
lock; xaddq %rsi, (%rdi) \n\
movq %rsi, %rax \n\
ret \n\
");
}
#elif defined (__sparcv9)
unsigned long
ace_atomic_add_long (volatile unsigned long *dest, long rhs)
{
__asm ("restore\n"
"ldx [%o0], %o2\n"
".again_add:\n"
"add %o2, %o1, %o3\n"
"casx [%o0], %o2, %o3\n"
"cmp %o2, %o3\n"
"bne,pn %xcc, .again_add\n"
"mov %o3, %o2\n"
"retl\n"
"add %o2, %o1, %o0\n");
}
unsigned long
ace_atomic_swap_long (volatile unsigned long *dest, unsigned long rhs)
{
__asm ("restore\n"
"ldx [%o0], %o2\n"
".again_swap:\n"
"mov %o1, %o3\n"
"casx [%o0], %o2, %o3\n"
"cmp %o2, %o3\n"
"bne,pn %xcc, .again_swap\n"
"mov %o3, %o2\n"
"retl\n"
"mov %o3, %o0\n");
}
unsigned long
ace_atomic_swap_add_long (volatile unsigned long *dest, long rhs)
{
__asm ("restore\n"
"ldx [%o0], %o2\n"
".again_swap_add:\n"
"mov %o2, %o4\n"
"add %o2, %o1, %o3\n"
"casx [%o0], %o2, %o3\n"
"cmp %o2, %o3\n"
"bne,pn %xcc, .again_swap_add\n"
"mov %o3, %o2\n"
"retl\n"
"mov %o4, %o0\n");
}
#else
unsigned long
ace_atomic_add_long (volatile unsigned long *dest, long rhs)
{
__asm ("restore\n"
"ld [%o0], %o2\n"
".again_add:\n"
"add %o2, %o1, %o3\n"
"cas [%o0], %o2, %o3\n"
"cmp %o2, %o3\n"
"bne,pn %icc, .again_add\n"
"mov %o3, %o2\n"
"retl\n"
"add %o2, %o1, %o0\n");
}
unsigned long
ace_atomic_swap_long (volatile unsigned long *dest, unsigned long rhs)
{
__asm ("restore\n"
"ld [%o0], %o2\n"
".again_swap:\n"
"mov %o1, %o3\n"
"cas [%o0], %o2, %o3\n"
"cmp %o2, %o3\n"
"bne,pn %icc, .again_swap\n"
"mov %o3, %o2\n"
"retl\n"
"mov %o3, %o0\n");
}
unsigned long
ace_atomic_swap_add_long (volatile unsigned long *dest, long rhs)
{
__asm ("restore\n"
"ld [%o0], %o2\n"
".again_swap_add:\n"
"mov %o2, %o4\n"
"add %o2, %o1, %o3\n"
"cas [%o0], %o2, %o3\n"
"cmp %o2, %o3\n"
"bne,pn %icc, .again_swap_add\n"
"mov %o3, %o2\n"
"retl\n"
"mov %o4, %o0\n");
}
# endif /* __sparcv9 */
#elif !defined (__GNUC__) && !defined (__INTEL_COMPILER)
/* Make compilers stop complaining about an empty translation unit */
static int shut_up_compiler = 0;
#endif /* ACE_INCLUDE_ATOMIC_OP_SPARC */

View File

@@ -0,0 +1,12 @@
/* -*- C++ -*- */
#ifndef ACE_ATOMIC_OP_SPARC_H
#define ACE_ATOMIC_OP_SPARC_H
extern "C"
{
unsigned long ace_atomic_add_long (volatile unsigned long *dest, long rhs);
unsigned long ace_atomic_swap_long (volatile unsigned long *dest, unsigned long rhs);
unsigned long ace_atomic_swap_add_long (volatile unsigned long *dest, long rhs);
}
#endif /* ACE_ATOMIC_OP_SPARC_H */

View File

@@ -0,0 +1,80 @@
#ifndef ACE_ATOMIC_OP_T_CPP
#define ACE_ATOMIC_OP_T_CPP
#include "ace/Atomic_Op_T.h"
#ifdef ACE_HAS_DUMP
# include "ace/Log_Category.h"
#endif /* ACE_HAS_DUMP */
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#if !defined (__ACE_INLINE__)
#include "ace/Atomic_Op_T.inl"
#endif /* __ACE_INLINE__ */
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
ACE_ALLOC_HOOK_DEFINE(ACE_Atomic_Op_Ex)
ACE_ALLOC_HOOK_DEFINE(ACE_Atomic_Op)
// *************************************************
template <class ACE_LOCK, class TYPE> ACE_LOCK &
ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::mutex (void)
{
// ACE_TRACE ("ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::mutex");
return this->mutex_;
}
template <class ACE_LOCK, class TYPE>
void
ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::dump (void) const
{
#if defined (ACE_HAS_DUMP)
// ACE_TRACE ("ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::dump");
ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
this->mutex_.dump ();
ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
#endif /* ACE_HAS_DUMP */
}
template <class ACE_LOCK, class TYPE>
ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::ACE_Atomic_Op_Ex (ACE_LOCK & mtx)
: mutex_ (mtx)
, value_ (0)
{
// ACE_TRACE ("ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::ACE_Atomic_Op_Ex");
}
template <class ACE_LOCK, class TYPE>
ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::ACE_Atomic_Op_Ex (
ACE_LOCK & mtx,
typename ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::arg_type c)
: mutex_ (mtx)
, value_ (c)
{
// ACE_TRACE ("ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::ACE_Atomic_Op_Ex");
}
// ****************************************************************
template <class ACE_LOCK, class TYPE>
ACE_Atomic_Op<ACE_LOCK, TYPE>::ACE_Atomic_Op (void)
: impl_ (this->own_mutex_)
{
// ACE_TRACE ("ACE_Atomic_Op<ACE_LOCK, TYPE>::ACE_Atomic_Op");
}
template <class ACE_LOCK, class TYPE>
ACE_Atomic_Op<ACE_LOCK, TYPE>::ACE_Atomic_Op (
typename ACE_Atomic_Op<ACE_LOCK, TYPE>::arg_type c)
: impl_ (own_mutex_, c)
{
// ACE_TRACE ("ACE_Atomic_Op<ACE_LOCK, TYPE>::ACE_Atomic_Op");
}
ACE_END_VERSIONED_NAMESPACE_DECL
#endif /* ACE_ATOMIC_OP_T_CPP */

View File

@@ -0,0 +1,357 @@
// -*- C++ -*-
//=============================================================================
/**
* @file Atomic_Op_T.h
*
* @author Douglas C. Schmidt <schmidt@uci.edu>
*/
//=============================================================================
#ifndef ACE_ATOMIC_OP_T_H
#define ACE_ATOMIC_OP_T_H
#include /**/ "ace/pre.h"
#include /**/ "ace/config-all.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
template<typename TYPE>
struct ACE_Type_Traits
{
typedef TYPE const & parameter_type;
};
template<>
struct ACE_Type_Traits<bool>
{
typedef bool parameter_type;
};
template<>
struct ACE_Type_Traits<char>
{
typedef char parameter_type;
};
template<>
struct ACE_Type_Traits<signed char>
{
typedef signed char parameter_type;
};
template<>
struct ACE_Type_Traits<unsigned char>
{
typedef unsigned char parameter_type;
};
template<>
struct ACE_Type_Traits<short>
{
typedef short parameter_type;
};
template<>
struct ACE_Type_Traits<unsigned short>
{
typedef unsigned short parameter_type;
};
template<>
struct ACE_Type_Traits<int>
{
typedef int parameter_type;
};
template<>
struct ACE_Type_Traits<unsigned int>
{
typedef unsigned int parameter_type;
};
template<>
struct ACE_Type_Traits<long>
{
typedef long parameter_type;
};
template<>
struct ACE_Type_Traits<unsigned long>
{
typedef unsigned long parameter_type;
};
template<>
struct ACE_Type_Traits<long long>
{
typedef long long parameter_type;
};
template<>
struct ACE_Type_Traits<unsigned long long>
{
typedef unsigned long long parameter_type;
};
template<>
struct ACE_Type_Traits<float>
{
typedef float parameter_type;
};
template<>
struct ACE_Type_Traits<double>
{
typedef double parameter_type;
};
template<>
struct ACE_Type_Traits<long double>
{
typedef long double parameter_type;
};
template<typename TYPE>
struct ACE_Type_Traits<TYPE*>
{
typedef TYPE* parameter_type;
};
/**
* @class ACE_Atomic_Op_Ex
*
* @brief Transparently parameterizes synchronization into basic
* arithmetic operations.
*
* This class is described in an article in the July/August 1994
* issue of the C++ Report magazine. It implements a
* templatized version of the Decorator pattern from the GoF book.
*
* ACE_Atomic_Op_Ex objects must be constructed with a reference
* to an existing lock. A single lock can be shared between
* multiple ACE_Atomic_Op_Ex objects. If you do not require this
* ability consider using the ACE_Atomic_Op class instead, which
* may be able to take advantage of platform-specific
* optimisations to provide atomic operations without requiring a
* lock.
*/
template <class ACE_LOCK, typename TYPE>
class ACE_Atomic_Op_Ex
{
public:
typedef typename ACE_Type_Traits<TYPE>::parameter_type arg_type;
// = Initialization methods.
/// Initialize @c value_ to 0.
ACE_Atomic_Op_Ex (ACE_LOCK & mtx);
/// Initialize @c value_ to c.
ACE_Atomic_Op_Ex (ACE_LOCK & mtx, arg_type c);
// = Accessors.
/// Atomically pre-increment @c value_.
TYPE operator++ (void);
/// Atomically post-increment @c value_.
TYPE operator++ (int);
/// Atomically increment @c value_ by rhs.
TYPE operator+= (arg_type rhs);
/// Atomically pre-decrement @c value_.
TYPE operator-- (void);
/// Atomically post-decrement @c value_.
TYPE operator-- (int);
/// Atomically decrement @c value_ by rhs.
TYPE operator-= (arg_type rhs);
/// Atomically compare @c value_ with rhs.
bool operator== (arg_type rhs) const;
/// Atomically compare @c value_ with rhs.
bool operator!= (arg_type rhs) const;
/// Atomically check if @c value_ greater than or equal to rhs.
bool operator>= (arg_type rhs) const;
/// Atomically check if @c value_ greater than rhs.
bool operator> (arg_type rhs) const;
/// Atomically check if @c value_ less than or equal to rhs.
bool operator<= (arg_type rhs) const;
/// Atomically check if @c value_ less than rhs.
bool operator< (arg_type rhs) const;
/// Atomically assign rhs to @c value_.
ACE_Atomic_Op_Ex<ACE_LOCK, TYPE> &operator= (arg_type rhs);
/// Atomically assign <rhs> to @c value_.
ACE_Atomic_Op_Ex<ACE_LOCK, TYPE> &operator= (
ACE_Atomic_Op_Ex<ACE_LOCK, TYPE> const & rhs);
/// Exchange value with @a newval.
TYPE exchange (TYPE newval);
/// Explicitly return @c value_.
TYPE value (void) const;
/// Dump the state of an object.
void dump (void) const;
// ACE_ALLOC_HOOK_DECLARE;
// Declare the dynamic allocation hooks.
/// Manage copying...
ACE_Atomic_Op_Ex (ACE_Atomic_Op_Ex<ACE_LOCK, TYPE> const &);
/**
* Returns a reference to the underlying ACE_LOCK. This makes it
* possible to acquire the lock explicitly, which can be useful in
* some cases if you instantiate the ACE_Atomic_Op_Ex with an
* ACE_Recursive_Mutex or ACE_Process_Mutex.
*
* @note The right name would be lock_, but HP/C++ will choke on that!
*/
ACE_LOCK & mutex (void);
/**
* Explicitly return @c value_ (by reference). This gives the user
* full, unrestricted access to the underlying value. This method
* will usually be used in conjunction with explicit access to the
* lock. Use with care ;-)
*/
TYPE & value_i (void);
private:
/// Type of synchronization mechanism.
ACE_LOCK & mutex_;
/// Current object decorated by the atomic op.
TYPE value_;
};
/**
* @class ACE_Atomic_Op
*
* @brief Transparently parameterizes synchronization into basic
* arithmetic operations.
*
* This class is described in an article in the July/August 1994
* issue of the C++ Report magazine. It implements a
* templatized version of the Decorator pattern from the GoF book.
*
* Certain platforms may provide a template specialization for
* ACE_Atomic_Op <ACE_Thread_Mutex, long> that provides optimized
* atomic integer operations without actually requiring a mutex.
*/
template <class ACE_LOCK, typename TYPE>
class ACE_Atomic_Op
{
public:
typedef typename ACE_Type_Traits<TYPE>::parameter_type arg_type;
/// Initialize @c value_ to 0.
ACE_Atomic_Op (void);
/// Initialize @c value_ to c.
ACE_Atomic_Op (arg_type c);
/// Manage copying...
ACE_Atomic_Op (ACE_Atomic_Op<ACE_LOCK, TYPE> const & c);
/// Atomically assign @a rhs to @c value_.
ACE_Atomic_Op<ACE_LOCK, TYPE> & operator= (arg_type rhs);
/// Atomically assign @a rhs to @c value_.
ACE_Atomic_Op<ACE_LOCK, TYPE> & operator= (
ACE_Atomic_Op<ACE_LOCK, TYPE> const & rhs);
/// Atomically pre-increment @c value_.
TYPE operator++ (void);
/// Atomically post-increment @c value_.
TYPE operator++ (int);
/// Atomically increment @c value_ by rhs.
TYPE operator+= (arg_type rhs);
/// Atomically pre-decrement @c value_.
TYPE operator-- (void);
/// Atomically post-decrement @c value_.
TYPE operator-- (int);
/// Atomically decrement @c value_ by @a rhs.
TYPE operator-= (arg_type rhs);
/// Atomically compare @c value_ with @a rhs.
bool operator== (arg_type rhs) const;
/// Atomically compare @c value_ with @a rhs.
bool operator!= (arg_type rhs) const;
/// Atomically check if @c value_ greater than or equal to @a rhs.
bool operator>= (arg_type rhs) const;
/// Atomically check if @c value_ greater than @a rhs.
bool operator> (arg_type rhs) const;
/// Atomically check if @c value_ less than or equal to @a rhs.
bool operator<= (arg_type rhs) const;
/// Atomically check if @c value_ less than @a rhs.
bool operator< (arg_type rhs) const;
/// Exchange value with @a newval.
TYPE exchange (TYPE newval);
/// Explicitly return @c value_.
TYPE value (void) const;
/// Dump the state of an object.
void dump (void) const;
/**
* Explicitly return @c value_ (by reference). This gives the user
* full, unrestricted access to the underlying value. This method
* will usually be used in conjunction with explicit access to the
* lock. Use with care ;-)
*/
TYPE & value_i (void);
private:
/// Type of synchronization mechanism.
ACE_LOCK own_mutex_;
/// Underlying atomic op implementation.
ACE_Atomic_Op_Ex <ACE_LOCK, TYPE> impl_;
};
ACE_END_VERSIONED_NAMESPACE_DECL
#if defined (__ACE_INLINE__)
#include "ace/Atomic_Op_T.inl"
#endif /* __ACE_INLINE__ */
#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
#include "ace/Atomic_Op_T.cpp"
#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
#pragma implementation ("Atomic_Op_T.cpp")
#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
#include /**/ "ace/post.h"
#endif /*ACE_ATOMIC_OP_T_H*/

View File

@@ -0,0 +1,346 @@
// -*- C++ -*-
#include "ace/Guard_T.h"
#include <algorithm>
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
//
// ACE_Atomic_Op_Ex inline functions
//
template <class ACE_LOCK, class TYPE>
ACE_INLINE TYPE
ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::operator++ (void)
{
// ACE_TRACE ("ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::operator++");
ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, this->value_);
return ++this->value_;
}
template <class ACE_LOCK, class TYPE>
ACE_INLINE TYPE
ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::operator+= (
typename ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::arg_type rhs)
{
// ACE_TRACE ("ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::operator+=");
ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, this->value_);
return this->value_ += rhs;
}
template <class ACE_LOCK, class TYPE>
ACE_INLINE TYPE
ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::operator-- (void)
{
// ACE_TRACE ("ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::operator--");
ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, this->value_);
return --this->value_;
}
template <class ACE_LOCK, class TYPE>
ACE_INLINE TYPE
ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::operator-= (
typename ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::arg_type rhs)
{
// ACE_TRACE ("ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::operator-=");
ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, this->value_);
return this->value_ -= rhs;
}
template <class ACE_LOCK, class TYPE>
ACE_INLINE
ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::ACE_Atomic_Op_Ex (
ACE_Atomic_Op_Ex<ACE_LOCK, TYPE> const & rhs)
: mutex_ (rhs.mutex_)
, value_ (rhs.value ()) // rhs.value() returns atomically
{
// ACE_TRACE ("ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::ACE_Atomic_Op_Ex");
}
template <class ACE_LOCK, class TYPE>
ACE_INLINE TYPE
ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::operator++ (int)
{
// ACE_TRACE ("ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::operator++");
ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, this->value_);
return this->value_++;
}
template <class ACE_LOCK, class TYPE>
ACE_INLINE TYPE
ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::operator-- (int)
{
// ACE_TRACE ("ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::operator--");
ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, this->value_);
return this->value_--;
}
template <class ACE_LOCK, class TYPE>
ACE_INLINE bool
ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::operator== (
typename ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::arg_type rhs) const
{
// ACE_TRACE ("ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::operator==");
ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, false);
return this->value_ == rhs;
}
template <class ACE_LOCK, class TYPE>
ACE_INLINE bool
ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::operator!= (
typename ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::arg_type rhs) const
{
// ACE_TRACE ("ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::operator!=");
return !(*this == rhs);
}
template <class ACE_LOCK, class TYPE>
ACE_INLINE bool
ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::operator>= (
typename ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::arg_type rhs) const
{
// ACE_TRACE ("ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::operator>=");
ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, false);
return this->value_ >= rhs;
}
template <class ACE_LOCK, class TYPE>
ACE_INLINE bool
ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::operator> (
typename ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::arg_type rhs) const
{
// ACE_TRACE ("ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::operator>");
ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, false);
return this->value_ > rhs;
}
template <class ACE_LOCK, class TYPE>
ACE_INLINE bool
ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::operator<= (
typename ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::arg_type rhs) const
{
// ACE_TRACE ("ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::operator<=");
ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, false);
return this->value_ <= rhs;
}
template <class ACE_LOCK, class TYPE>
ACE_INLINE bool
ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::operator< (
typename ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::arg_type rhs) const
{
// ACE_TRACE ("ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::operator<");
ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, false);
return this->value_ < rhs;
}
template <class ACE_LOCK, class TYPE>
ACE_INLINE ACE_Atomic_Op_Ex<ACE_LOCK, TYPE> &
ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::operator= (
ACE_Atomic_Op_Ex<ACE_LOCK, TYPE> const & rhs)
{
// ACE_TRACE ("ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::operator=");
ACE_Atomic_Op_Ex<ACE_LOCK, TYPE> tmp (rhs);
ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, *this);
std::swap (this->value_, tmp.value_);
return *this;
}
template <class ACE_LOCK, class TYPE>
ACE_INLINE TYPE
ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::exchange (TYPE newval)
{
// ACE_TRACE ("ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::exchange");
ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, this->value_);
std::swap (this->value_, newval);
return newval;
}
template <class ACE_LOCK, class TYPE>
ACE_INLINE TYPE
ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::value (void) const
{
// ACE_TRACE ("ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::value");
ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, this->value_);
return this->value_;
}
template <class ACE_LOCK, class TYPE>
ACE_INLINE TYPE &
ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::value_i (void)
{
// Explicitly return <value_> (by reference). This gives the user
// full, unrestricted access to the underlying value. This method
// will usually be used in conjunction with explicit access to the
// lock. Use with care ;-)
return this->value_;
}
template <class ACE_LOCK, class TYPE>
ACE_INLINE ACE_Atomic_Op_Ex<ACE_LOCK, TYPE> &
ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::operator= (
typename ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::arg_type rhs)
{
// ACE_TRACE ("ACE_Atomic_Op_Ex<ACE_LOCK, TYPE>::operator=");
ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, *this);
this->value_ = rhs;
return *this;
}
//
// ACE_Atomic_Op inline functions
//
template <class ACE_LOCK, class TYPE> ACE_INLINE
ACE_Atomic_Op<ACE_LOCK, TYPE>::ACE_Atomic_Op (
ACE_Atomic_Op<ACE_LOCK, TYPE> const & rhs)
: impl_ (own_mutex_, rhs.value ())
{
// ACE_TRACE ("ACE_Atomic_Op<ACE_LOCK, TYPE>::ACE_Atomic_Op");
}
template <class ACE_LOCK, class TYPE>
ACE_INLINE ACE_Atomic_Op<ACE_LOCK, TYPE> &
ACE_Atomic_Op<ACE_LOCK, TYPE>::operator= (
typename ACE_Atomic_Op<ACE_LOCK, TYPE>::arg_type i)
{
this->impl_ = i;
return *this;
}
template <class ACE_LOCK, class TYPE>
ACE_INLINE ACE_Atomic_Op<ACE_LOCK, TYPE> &
ACE_Atomic_Op<ACE_LOCK, TYPE>::operator= (
ACE_Atomic_Op<ACE_LOCK, TYPE> const & rhs)
{
this->impl_ = rhs.impl_;
return *this;
}
template <class ACE_LOCK, class TYPE>
ACE_INLINE TYPE
ACE_Atomic_Op<ACE_LOCK, TYPE>::operator++ (void)
{
return ++this->impl_;
}
template <class ACE_LOCK, class TYPE>
ACE_INLINE TYPE
ACE_Atomic_Op<ACE_LOCK, TYPE>::operator++ (int)
{
return this->impl_++;
}
template <class ACE_LOCK, class TYPE>
ACE_INLINE TYPE
ACE_Atomic_Op<ACE_LOCK, TYPE>::operator+= (
typename ACE_Atomic_Op<ACE_LOCK, TYPE>::arg_type rhs)
{
return this->impl_ += rhs;
}
template <class ACE_LOCK, class TYPE>
ACE_INLINE TYPE
ACE_Atomic_Op<ACE_LOCK, TYPE>::operator-- (void)
{
return --this->impl_;
}
template <class ACE_LOCK, class TYPE>
ACE_INLINE TYPE
ACE_Atomic_Op<ACE_LOCK, TYPE>::operator-- (int)
{
return this->impl_--;
}
template <class ACE_LOCK, class TYPE>
ACE_INLINE TYPE
ACE_Atomic_Op<ACE_LOCK, TYPE>::operator-= (
typename ACE_Atomic_Op<ACE_LOCK, TYPE>::arg_type rhs)
{
return this->impl_ -= rhs;
}
template <class ACE_LOCK, class TYPE>
ACE_INLINE bool
ACE_Atomic_Op<ACE_LOCK, TYPE>::operator== (
typename ACE_Atomic_Op<ACE_LOCK, TYPE>::arg_type rhs) const
{
return this->impl_ == rhs;
}
template <class ACE_LOCK, class TYPE>
ACE_INLINE bool
ACE_Atomic_Op<ACE_LOCK, TYPE>::operator!= (
typename ACE_Atomic_Op<ACE_LOCK, TYPE>::arg_type rhs) const
{
return this->impl_ != rhs;
}
template <class ACE_LOCK, class TYPE>
ACE_INLINE bool
ACE_Atomic_Op<ACE_LOCK, TYPE>::operator>= (
typename ACE_Atomic_Op<ACE_LOCK, TYPE>::arg_type rhs) const
{
return this->impl_ >= rhs;
}
template <class ACE_LOCK, class TYPE>
ACE_INLINE bool
ACE_Atomic_Op<ACE_LOCK, TYPE>::operator> (
typename ACE_Atomic_Op<ACE_LOCK, TYPE>::arg_type rhs) const
{
return this->impl_ > rhs;
}
template <class ACE_LOCK, class TYPE>
ACE_INLINE bool
ACE_Atomic_Op<ACE_LOCK, TYPE>::operator<= (
typename ACE_Atomic_Op<ACE_LOCK, TYPE>::arg_type rhs) const
{
return this->impl_ <= rhs;
}
template <class ACE_LOCK, class TYPE>
ACE_INLINE bool
ACE_Atomic_Op<ACE_LOCK, TYPE>::operator< (
typename ACE_Atomic_Op<ACE_LOCK, TYPE>::arg_type rhs) const
{
return this->impl_ < rhs;
}
template <class ACE_LOCK, class TYPE>
ACE_INLINE TYPE
ACE_Atomic_Op<ACE_LOCK, TYPE>::exchange (TYPE newval)
{
return this->impl_.exchange (newval);
}
template <class ACE_LOCK, class TYPE>
ACE_INLINE TYPE
ACE_Atomic_Op<ACE_LOCK, TYPE>::value (void) const
{
return this->impl_.value ();
}
template <class ACE_LOCK, class TYPE>
ACE_INLINE void
ACE_Atomic_Op<ACE_LOCK, TYPE>::dump (void) const
{
#if defined (ACE_HAS_DUMP)
this->impl_.dump ();
#endif /* ACE_HAS_DUMP */
return;
}
template <class ACE_LOCK, class TYPE>
ACE_INLINE TYPE &
ACE_Atomic_Op<ACE_LOCK, TYPE>::value_i (void)
{
return this->impl_.value_i ();
}
ACE_END_VERSIONED_NAMESPACE_DECL

View File

@@ -0,0 +1,11 @@
#include "ace/Auto_Event.h"
#if !defined (__ACE_INLINE__)
//#include "ace/Auto_Event.inl"
#endif /* __ACE_INLINE__ */
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
ACE_END_VERSIONED_NAMESPACE_DECL

View File

@@ -0,0 +1,129 @@
// -*- C++ -*-
//==========================================================================
/**
* @file Auto_Event.h
*
* Moved from Synch.h.
*
* @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
*/
//==========================================================================
#ifndef ACE_AUTO_EVENT_H
#define ACE_AUTO_EVENT_H
#include /**/ "ace/pre.h"
#include /**/ "ace/ACE_export.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "ace/Event.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
/**
* @class ACE_Auto_Event
*
* @brief Auto Events.
*
* Specialization of Event mechanism which wakes up one waiting
* thread on @c signal. All platforms support process-scope locking
* support. However, only Win32 platforms support global naming and
* system-scope locking support.
*/
template <class TIME_POLICY = ACE_System_Time_Policy>
class ACE_Auto_Event_T : public ACE_Event_T<TIME_POLICY>
{
public:
/// Constructor which will create auto event
ACE_Auto_Event_T (int initial_state = 0,
int type = USYNC_THREAD,
const char *name = 0,
void *arg = 0) : ACE_Event_T<TIME_POLICY> (0,
initial_state,
type,
ACE_TEXT_CHAR_TO_TCHAR (name),
arg)
{
}
#if defined (ACE_HAS_WCHAR)
/// Constructor which will create auto event (wchar_t version)
ACE_Auto_Event_T (int initial_state,
int type,
const wchar_t *name,
void *arg = 0) : ACE_Event_T<TIME_POLICY> (0,
initial_state,
type,
ACE_TEXT_WCHAR_TO_TCHAR (name),
arg)
{
}
#endif /* ACE_HAS_WCHAR */
/// Default dtor.
virtual ~ACE_Auto_Event_T (void)
{
}
/// Dump the state of an object.
void dump (void) const
{
#if defined (ACE_HAS_DUMP)
ACE_Event_T<TIME_POLICY>::dump ();
#endif /* ACE_HAS_DUMP */
}
/// Declare the dynamic allocation hooks
ACE_ALLOC_HOOK_DECLARE;
};
class ACE_Auto_Event :
public ACE_Auto_Event_T<ACE_System_Time_Policy>
{
public:
/// Constructor which will create auto event
ACE_Auto_Event (int initial_state = 0,
int type = USYNC_THREAD,
const char *name = 0,
void *arg = 0)
: ACE_Auto_Event_T<ACE_System_Time_Policy> (initial_state, type, name, arg)
{
}
#if defined (ACE_HAS_WCHAR)
/// Constructor which will create auto event (wchar_t version)
ACE_Auto_Event (int initial_state,
int type,
const wchar_t *name,
void *arg = 0)
: ACE_Auto_Event_T<ACE_System_Time_Policy> (initial_state, type, name, arg)
{
}
#endif /* ACE_HAS_WCHAR */
/// Default dtor.
virtual ~ACE_Auto_Event (void)
{
}
};
ACE_END_VERSIONED_NAMESPACE_DECL
#if defined (__ACE_INLINE__)
#include "ace/Auto_Event.inl"
#endif /* __ACE_INLINE__ */
#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
#include "ace/Auto_Event.cpp"
#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
#pragma implementation ("Auto_Event.cpp")
#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
#include /**/ "ace/post.h"
#endif /* ACE_AUTO_EVENT_H */

View File

@@ -0,0 +1,4 @@
// -*- C++ -*-
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
ACE_END_VERSIONED_NAMESPACE_DECL

View File

@@ -0,0 +1,37 @@
#ifndef ACE_AUTO_FUNCTOR_CPP
#define ACE_AUTO_FUNCTOR_CPP
#include "ace/Auto_Functor.h"
#if !defined(__ACE_INLINE__)
# include "ace/Auto_Functor.inl"
#endif /* __ACE_INLINE__ */
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
template<typename X, typename Functor>
ACE_Utils::Auto_Functor<X,Functor>::~Auto_Functor()
{
reset(0);
}
template<typename X, typename Functor> void
ACE_Utils::Auto_Functor<X,Functor>::reset(X * p)
{
if(p_ != 0)
{
f_(p_);
}
p_ = p;
}
template<typename X, typename Functor>void
ACE_Utils::Auto_Functor<X,Functor>::reset(X * p, Functor f)
{
reset(p);
f_ = f;
}
ACE_END_VERSIONED_NAMESPACE_DECL
#endif /*ACE_AUTO_FUNCTOR_CPP*/

View File

@@ -0,0 +1,118 @@
// -*- C++ -*-
//=============================================================================
/**
* @file Auto_Functor.h
*
* @author Carlos O'Ryan <coryan@atdesk.com>
*/
//=============================================================================
#ifndef ACE_AUTO_FUNCTOR_H
#define ACE_AUTO_FUNCTOR_H
#include /**/ "ace/pre.h"
#include /**/ "ace/config-all.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "ace/Global_Macros.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
namespace ACE_Utils
{
/**
* @class Auto_Functor_Ref
*
* @brief Helper class to implement assignment and copy-construction
* as expected
*/
template<typename X, typename Functor>
struct Auto_Functor_Ref
{
X * p_;
Functor f_;
Auto_Functor_Ref(X * p, Functor f);
};
/**
* @class Auto_Functor
*
* @brief Helper template to implement auto_ptr<>-like classes, but
* executing a functor in the destructor, instead of always
* deleting things.
*
* The functor is called in the destructor, and it must implement:
*
* Functor() throw();<BR>
* Functor(Functor const &) throw();<BR>
* Functor & operator=(Functor const &) throw();<BR>
* void operator()(X * p) throw();<BR>
*/
template<typename X, typename Functor>
class Auto_Functor
{
public:
typedef X element_type;
typedef Functor functor_type;
/// Constructor
explicit Auto_Functor (X * p = 0,
Functor functor = Functor()); // throw()
Auto_Functor (Auto_Functor & rhs); // throw()
Auto_Functor<X,Functor>& operator= (Auto_Functor & rhs); // throw()
template<typename Y>
Auto_Functor(Auto_Functor<Y,Functor>& rhs); // throw()
template<typename Y>
Auto_Functor<X,Functor>& operator= (Auto_Functor<Y,Functor>& rhs); // throw()
~Auto_Functor(); // throw()
X & operator*() const; // throw()
X * operator->() const; // throw()
X * get(); // throw()
X * release(); // throw()
void reset (X * p = 0); // throw()
void reset (X * p, Functor f); // throw()
Functor const & functor() const; // throw()
Auto_Functor(Auto_Functor_Ref<X,Functor> rhs); // throw()
Auto_Functor<X,Functor> & operator=(Auto_Functor_Ref<X,Functor> rhs); // throw()
template<typename Y> operator Auto_Functor_Ref<Y,Functor>(); // throw()
template<typename Y> operator Auto_Functor<Y,Functor>(); // throw()
private:
X * p_;
Functor f_;
};
} // namespace ACE_Utils
ACE_END_VERSIONED_NAMESPACE_DECL
#if defined(__ACE_INLINE__)
# include "ace/Auto_Functor.inl"
#endif /* __ACE_INLINE__ */
#if defined(ACE_TEMPLATES_REQUIRE_SOURCE)
# include "ace/Auto_Functor.cpp"
#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
#include /**/ "ace/post.h"
#endif /* ACE_AUTO_FUNCTOR_H*/

View File

@@ -0,0 +1,117 @@
// -*- C++ -*-
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
template<typename X, typename Functor> ACE_INLINE
ACE_Utils::Auto_Functor_Ref<X,Functor>::
Auto_Functor_Ref(X * p, Functor f)
: p_(p)
, f_(f)
{
}
template<typename X, typename Functor> ACE_INLINE
ACE_Utils::Auto_Functor<X,Functor>::Auto_Functor(X * p, Functor f)
: p_(p)
, f_(f)
{
}
template<typename X, typename Functor> ACE_INLINE
ACE_Utils::Auto_Functor<X,Functor>::Auto_Functor(Auto_Functor & rhs)
: p_(rhs.release())
, f_(rhs.f_)
{
}
template<typename X, typename Functor>
ACE_INLINE ACE_Utils::Auto_Functor<X,Functor>&
ACE_Utils::Auto_Functor<X,Functor>:: operator=(Auto_Functor & rhs)
{
reset(rhs.release());
f_ = rhs.f_;
return *this;
}
template<typename X, typename Functor> template<typename Y> ACE_INLINE
ACE_Utils::Auto_Functor<X,Functor>::Auto_Functor(Auto_Functor<Y,Functor>& rhs)
: p_(rhs.release())
, f_(rhs.f_)
{
}
template<typename X, typename Functor> template<typename Y>
ACE_INLINE ACE_Utils::Auto_Functor<X,Functor>&
ACE_Utils::Auto_Functor<X,Functor>::operator=(Auto_Functor<Y,Functor>& rhs)
{
reset(rhs.release());
return *this;
}
template<typename X, typename Functor> ACE_INLINE X &
ACE_Utils::Auto_Functor<X,Functor>::operator*() const
{
return *p_;
}
template<typename X, typename Functor>
ACE_INLINE X *
ACE_Utils::Auto_Functor<X,Functor>::operator->() const
{
return p_;
}
template<typename X, typename Functor>
ACE_INLINE X *
ACE_Utils::Auto_Functor<X,Functor>::get()
{
return p_;
}
template<typename X, typename Functor>
ACE_INLINE X *
ACE_Utils::Auto_Functor<X,Functor>::release()
{
X * tmp = p_;
p_ = 0;
return tmp;
}
template<typename X, typename Functor>
ACE_INLINE Functor const &
ACE_Utils::Auto_Functor<X,Functor>::functor() const
{
return f_;
}
template<typename X, typename Functor> ACE_INLINE
ACE_Utils::Auto_Functor<X,Functor>::Auto_Functor(Auto_Functor_Ref<X,Functor> rhs)
: p_(rhs.p_)
, f_(rhs.f_)
{
}
template<typename X, typename Functor>
ACE_INLINE ACE_Utils::Auto_Functor<X,Functor> &
ACE_Utils::Auto_Functor<X,Functor>::operator=(Auto_Functor_Ref<X,Functor> rhs)
{
if(rhs.p_ != p_)
{
reset(rhs.p_);
f_ = rhs.f_;
}
return *this;
}
template<typename X, typename Functor> template<typename Y> ACE_INLINE
ACE_Utils::Auto_Functor<X,Functor>::operator ACE_Utils::Auto_Functor_Ref<Y,Functor>()
{
return ACE_Utils::Auto_Functor_Ref<Y,Functor>(release(), f_);
}
template<typename X, typename Functor> template<typename Y> ACE_INLINE
ACE_Utils::Auto_Functor<X,Functor>::operator ACE_Utils::Auto_Functor<Y,Functor>()
{
return ACE_Utils::Auto_Functor<Y,Functor>(release(), f_);
}
ACE_END_VERSIONED_NAMESPACE_DECL

View File

@@ -0,0 +1,32 @@
#ifndef ACE_AUTO_INCDEC_T_CPP
#define ACE_AUTO_INCDEC_T_CPP
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "ace/Auto_IncDec_T.h"
#include "ace/Log_Category.h"
#if !defined (__ACE_INLINE__)
#include "ace/Auto_IncDec_T.inl"
#endif /* __ACE_INLINE__ */
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
ACE_ALLOC_HOOK_DEFINE(ACE_Auto_IncDec)
template <class ACE_SAFELY_INCREMENTABLE_DECREMENTABLE> void
ACE_Auto_IncDec<ACE_SAFELY_INCREMENTABLE_DECREMENTABLE>::dump (void) const
{
#if defined (ACE_HAS_DUMP)
// ACE_TRACE ("ACE_Auto_IncDec<ACE_SAFELY_INCREMENTABLE_DECREMENTABLE>::dump");
ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
#endif /* ACE_HAS_DUMP */
}
ACE_END_VERSIONED_NAMESPACE_DECL
#endif /* ACE_AUTO_INCDEC_T_CPP */

View File

@@ -0,0 +1,76 @@
// -*- C++ -*-
//=============================================================================
/**
* @file Auto_IncDec_T.h
*
* @author Edan Ayal <EdanA@cti2.com>
*/
//=============================================================================
#ifndef ACE_AUTO_INCDEC_T_H
#define ACE_AUTO_INCDEC_T_H
#include /**/ "ace/pre.h"
#include /**/ "ace/config-all.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "ace/Global_Macros.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
/**
* @class ACE_Auto_IncDec
*
* @brief This class automatically increments and decrements a
* parameterized counter.
*
* This data structure is meant to be used within a method,
* function, or scope. The actual parameter given for the
* @c ACE_SAFELY_INCREMENTABLE_DECREMENTABLE template parameter
* must provide at least operators ++ and --.
*/
template <class ACE_SAFELY_INCREMENTABLE_DECREMENTABLE>
class ACE_Auto_IncDec
{
public:
/// Implicitly increment the counter.
ACE_Auto_IncDec (ACE_SAFELY_INCREMENTABLE_DECREMENTABLE &counter);
/// Implicitly decrement the counter.
~ACE_Auto_IncDec (void);
/// Dump the state of an object.
void dump (void) const;
protected:
/// Reference to the @c ACE_SAFELY_INCREMENTABLE_DECREMENTABLE counter
/// we're incrementing/decrementing.
ACE_SAFELY_INCREMENTABLE_DECREMENTABLE &counter_;
private:
ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Auto_IncDec<ACE_SAFELY_INCREMENTABLE_DECREMENTABLE> &))
ACE_UNIMPLEMENTED_FUNC (ACE_Auto_IncDec (const ACE_Auto_IncDec<ACE_SAFELY_INCREMENTABLE_DECREMENTABLE> &))
};
ACE_END_VERSIONED_NAMESPACE_DECL
#if defined (__ACE_INLINE__)
#include "ace/Auto_IncDec_T.inl"
#endif /* __ACE_INLINE__ */
#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
#include "ace/Auto_IncDec_T.cpp"
#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
#pragma implementation ("Auto_IncDec_T.cpp")
#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
#include /**/ "ace/post.h"
#endif /* ACE_AUTO_INCDEC_T_H */

View File

@@ -0,0 +1,22 @@
// -*- C++ -*-
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
// Implicitly and automatically increment the counter.
template <class ACE_SAFELY_INCREMENTABLE_DECREMENTABLE> ACE_INLINE
ACE_Auto_IncDec<ACE_SAFELY_INCREMENTABLE_DECREMENTABLE>::ACE_Auto_IncDec
(ACE_SAFELY_INCREMENTABLE_DECREMENTABLE &counter)
: counter_ (counter)
{
++this->counter_;
}
// Implicitly and automatically decrement the counter.
template <class ACE_SAFELY_INCREMENTABLE_DECREMENTABLE> ACE_INLINE
ACE_Auto_IncDec<ACE_SAFELY_INCREMENTABLE_DECREMENTABLE>::~ACE_Auto_IncDec (void)
{
--this->counter_;
}
ACE_END_VERSIONED_NAMESPACE_DECL

View File

@@ -0,0 +1,19 @@
#ifndef ACE_AUTO_PTR_CPP
#define ACE_AUTO_PTR_CPP
#include "ace/Auto_Ptr.h"
#if !defined (__ACE_INLINE__)
#include "ace/Auto_Ptr.inl"
#endif /* __ACE_INLINE__ */
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
ACE_ALLOC_HOOK_DEFINE(ACE_Auto_Basic_Ptr)
ACE_ALLOC_HOOK_DEFINE(ACE_Auto_Basic_Array_Ptr)
ACE_END_VERSIONED_NAMESPACE_DECL
#endif /* ACE_AUTO_PTR_CPP */

Some files were not shown because too many files have changed in this diff Show More