Professional Documents
Culture Documents
Advanced C++
Advanced C++
Advanced C++
Department of EECS
Vanderbilt University
(615) 343-8197
Sponsors
NSF, DARPA, ATD, BBN, Boeing, Cisco, Comverse, GDIS, Experian, Global MT,
Hughes, Kodak, Krones, Lockheed, Lucent, Microsoft, Mitre, Motorola, NASA, Nokia,
Nortel, OCI, Oresis, OTI, QNX, Raytheon, SAIC, Siemens SCR, Siemens MED,
Siemens ZT, Sprint, Telcordia, USENIX
Douglas C. Schmidt
APPLICATIONS
HUD
Nav
WTS
EVENT
CHANNEL
AVIONICS
REPLICATION
SERVICE
Cons
Cons
Cons
DISTRIBUTION MIDDLEWARE
Historically, apps
built atop OS
Today, apps built
atop middleware
Middleware has
multiple layers
Just like network
protocol stacks
HARDWARE DEVICES
www.cs.wustl.edu/schmidt/PDF/
middleware-chapter.pdf
Vanderbilt University
Douglas C. Schmidt
Leverage hardware/software
maxfdp1
CLIENT
CLIENT
read_fds
WORK
REQUEST
WORK
REQUEST
WORK
REQUEST
CLIENT
WORK
REQUEST
CLIENT
Increase performance
e.g., overlap computation and
communication
SERVER
Improve response-time
CLIENT
WORK
REQUEST
CLIENT
WORK
REQUEST
Vanderbilt University
WORK
REQUEST
CLIENT
Douglas C. Schmidt
PRINTER
COMPUTER
CD ROM
FILE
SYSTEM
NAME
SERVICE
CYCLE
SERVICE
DISPLAY
SERVICE
NETWORK
FI LE
SERVICE
PRINT
SERVICE
CD ROM
PRINTER
FILE SYSTEM
Vanderbilt University
Collaboration
interworking
Performance
and locality
! connectivity and
! multi-processing
!
!
Extensibility
dynamic
configuration and reconfiguration
Cost effectiveness
open
systems and resource sharing
Douglas C. Schmidt
e.g., must address complex topics that are less problematic or not
relevant for non-concurrent, stand-alone applications
OO techniques and OO language features help to enhance software
quality factors
Vanderbilt University
Douglas C. Schmidt
Caveats
OO is not a panacea
Multi-threading
Multi-processing
Synchronization
Shared memory
Explicit dynamic linking
Communication protocols and IPC mechanisms
Vanderbilt University
Douglas C. Schmidt
Tutorial Outline
Brief overview of key OO networking and concurrency concepts and
OS platform mechanisms
Vanderbilt University
Douglas C. Schmidt
Vanderbilt University
Douglas C. Schmidt
Sources of Complexity
Inherent complexity
PRINTER
COMPUTER
CD ROM
FILE
SYSTEM
NAME
SERVICE
CYCLE
SERVICE
DISPLAY
SERVICE
NETWORK
FI LE
SERVICE
PRINT
SERVICE
CD ROM
PRINTER
FILE SYSTEM
Vanderbilt University
Latency
Reliability
Synchronization
Deadlock
Accidental Complexity
Low-level APIs
Poor debugging tools
Algorithmic
decomposition
Continuous
re-invention
8
Douglas C. Schmidt
Distributed programming
Fair scheduling
Performance optimization
and tuning
Vanderbilt University
Douglas C. Schmidt
10
Douglas C. Schmidt
OO Contributions to Concurrent
and Distributed Applications
Concurrent network programming is Patterns and frameworks elevate
traditionally performed using
development level to focus on
low-level OS mechanisms, e.g.,
application concerns, e.g.,
fork/exec
Shared memory and semaphores
Memory-mapped files
Signals
sockets/select
Low-level thread APIs
Vanderbilt University
Douglas C. Schmidt
Overview of Patterns
Patterns represent solutions to problems that arise when developing
software within a particular context
Vanderbilt University
12
Do
CALL
: BROKER
: QUOTER
4: METHOD
RETURN
3:
CLIENT
NETWORK
PROXY
RESPONSE
: QUOTER
2: FORWARD
REQUEST
SERVER
Vanderbilt University
Douglas C. Schmidt
Vanderbilt University
14
Douglas C. Schmidt
LOCAL
MATH
CLASSES
INVOCATIONS
ADT
DATABASE
CLASSES
CLASSES
GUI
GLUE
EVENT
LOOP
NETWORK
CLASSES
CODE
IPC
CLASSES
(A) CLASS
LIBRARY ARCHITECTURE
NETWORKING
EVENT
CLASSES
APPLICATIONSPECIFIC
INVOKES
GUI
CALL
BACKS
FUNCTIONALITY
EVENT
LOOP
MATH
CLASSES
DATABASE
(B) FRAMEWORK
Vanderbilt University
Class libraries
Frameworks
LOOP
ADT
Key distinctions
EVENT
LOOP
ARCHITECTURE
Reusable, semi-complete
applications
Domain-specific
Broader in scope
Active
15
Douglas C. Schmidt
NETWORKED
SERVICE
COMPONENTS
LAYER
TOKEN
SERVER
LOGGING
SERVER
C++
WRAPPER
FACADE
LAYER
TIME
SERVER
SERVICE
HANDLER
PROCESS/
THREAD
MANAGERS
SYNCH
WRAPPERS
ACCEPTOR
STREAMS
SPIPE
SAP
GATEWAY
SERVER
NAME
SERVER
FRAMEWORK
LAYER
SOCK SAP/
TLI SAP
CORBA
HANDLER
CONNECTOR
LOG
MSG
FIFO
SAP
SERVICE
CONFIGURATOR
REACTOR/
PROACTOR
SHARED
MALLOC
MEM
MAP
FILE
SAP
OS ADAPTATION LAYER
C
APIS
PROCESSES/
THREADS
WIN32 NAMED
PIPES & UNIX
STREAM PIPES
PROCESS/THREAD
SUBSYSTEM
SOCKETS/
TLI
UNIX
FIFOS
COMMUNICATION
SUBSYSTEM
SELECT/
IO COMP
DYNAMIC
LINKING
SHARED
MEMORY
FILE SYS
APIS
www.cs.wustl.edu/schmidt/ACE.html
Vanderbilt University
16
Douglas C. Schmidt
ACE Statistics
ACE library contains 250,000
lines of C++
schmidt/ACE-users.html
Currently used by
dozens of companies
Bellcore, BBN,
Boeing, Ericsson,
Hughes, Kodak,
Lockheed, Lucent,
Motorola, Nokia,
Nortel, Raytheon,
SAIC, Siemens, etc.
Supported commercially
by Riverace
www.riverace.com
Vanderbilt University
17
Douglas C. Schmidt
Reactor
Proactor
Service
Configurator
Streams
Task
18
Douglas C. Schmidt
Thread-per
Request
Thread-per
Session
Component
Configurator
Leader/
Followers
Asynchronous
Completion
Token
Reactor
External
Polymorphism
Concurrency
Patterns
Connector
Half-Sync/
Half-Async
Thread
Pool
Thread
Specific
Storage
Acceptor
Proactor
Double
Checked
Locking
ThreadSafe
Interface
Wrapper
Facade
Scoped
Locking
Strategized
Locking
Event
Patterns
Vanderbilt University
Object
Lifetime
Manager
Initialization Synchronization
Patterns
Patterns
Observation
Failures rarely result from
unknown scientific
principles, but from failing
to apply proven
engineering practices and
patterns
Benefits of Patterns
Facilitate design reuse
Preserve crucial design
information
Guide design choices
19
Douglas C. Schmidt
in args
CLIENT
OBJ
REF
operation()
OBJECT
(SERVANT)
IDL
IDL
STUBS
IOP
ORB RUN-TIME
SKELETON
SCHEDULER
REAL-TIME
OBJECT
ADAPTER
OS KERNEL
REAL-TIME I/O
SUBSYSTEM
HIGH-SPEED
NETWORK INTERFACE
PLUGGABLE
ORB & XPORT
PROTOCOLS
ACE
COMPONENTS
NETWORK
IOP
OS KERNEL
REAL-TIME I/O
SUBSYSTEM
HIGH-SPEED
NETWORK INTERFACE
www.cs.wustl.edu/schmidt/TAO.
html
Vanderbilt University
A real-time,
high-performance
ORB
Leverages ACE
Runs on POSIX,
Windows,
RTOSs
Related efforts !
QuO at BBN
MIC/GME at
Vanderbilt
XOTS
20
Douglas C. Schmidt
TAO Statistics
TAO order of magnitude
50 person-years of effort
Vanderbilt University
21
Douglas C. Schmidt
1: GET ~schmidt
HTTP/1.0
2: index.html
WWW
SERVER
PROTOCOL
HANDLERS
HTML
PARSER
GUI
DISPATCHER
REQUESTER
GRAPHICS
ADAPTER
COMMUNICATION PROTOCOL
(E.G., HTTP)
OS KERNEL
OS KERNEL
OS I/O SUBSYSTEM
OS I/O SUBSYSTEM
NETWORK ADAPTERS
NETWORK ADAPTERS
NETWORK
www.cs.wustl.edu/jxh/
research/
Vanderbilt University
JAWS Overview
A high-performance
Web server
Flexible concurrency
and dispatching
mechanisms
Leverages the ACE
framework
Ported to most OS
platforms
Used commercially by
CacheFlow
www.cacheflow.com
22
Douglas C. Schmidt
Java ACE
DISTRIBUTED
SERVICES AND
COMPONENTS
FRAMEWORKS
AND CLASS
CATEGORIES
TOKEN
LOGGING
NAME
TIME
SERVER
SERVER
SERVER
SERVER
ACCEPTOR
SERVICE
CONNECTOR
HANDLER
Java ACE
Overview
A Java version
of ACE
JAVA
SYNCH
WRAPPERS WRAPPERS
SOCK_SAP
THREAD
LOG
TIMER
SERVICE
MANAGER
MSG
QUEUE
CONFIGURATOR
www.cs.wustl.edu/schmidt/JACE.html
www.cs.wustl.edu/schmidt/C++2java.
html
www.cs.wustl.edu/schmidt/PDF/
MedJava.pdf
Vanderbilt University
Used for
medical
imaging
prototype
23
Do
P1
LOCAL
P2
IPC
CONSOLE
CLIENT
LOGGING
DAEMON
RE
MO
TE
P3
IPC
SERVER LOGGING
DAEMON
HA
OST A
HOST
SERVER
CLIENT
RE
MO
TE
IPC
HOST
B B
NETWORK
HOST
P1
CLIENT
P2
LOCAL
IPC
STORAGE
DEVICE
CLIENT
LOGGING
DAEMON
P3
Douglas C. Schmidt
and
ACE_DEBUG ((LM_DEBUG,
"(%t) sending to server %s", server_host));
25
Douglas C. Schmidt
Vanderbilt University
26
Do
NETWORK
CLIENT
SERVER
LOGGING DAEMON
maxhandlep1
acceptor
read_handles
CONNECTION
REQUEST
LOGGING
RECORDS
CLIENT
LOGGING
RECORDS
CLIENT
LOGGING
RECORDS
CLIENT
Vanderbilt University
Vanderbilt University
Do
Vanderbilt University
Do
Do
Vanderbilt University
Do
Do
Vanderbilt University
Vanderbilt University
Do
Do
Do
Vanderbilt University
Douglas C. Schmidt
36
Douglas C. Schmidt
Vanderbilt University
37
Douglas C. Schmidt
OO Contributions to Software
Patterns facilitate the large-scale reuse of software architecture
Vanderbilt University
38
Douglas C. Schmidt
Acceptor
Reactor
STRATEGIC
PATTERNS
TACTICAL PATTERNS
Adapter
Iterator
Factory
Method
Template
Method
Wrapper
Facade
Strategic and tactical are relative to the context and abstraction level
Vanderbilt University
39
Douglas C. Schmidt
40
Douglas C. Schmidt
41
Do
CONNECTIONORIENTED
COMPONENTS
APPLICATIONSPECIFIC
COMPONENTS
Logging
Acceptor
SOCK_Stream
Null_Synch
n
<<activates>>
Logging
Handler
SVC_HANDLER
PEER_ACCEPTOR
Svc
Handler
Acceptor
ACE
FRAMEWORK
COMPONENTS
PEER
ACCEPTOR
PEER
STREAM
Connection
Stream
IPC_SAP
Service
Configurator
Concurrency
Vanderbilt University
PEER_STREAM
SYNCH_STRAT
Reactor
Douglas C. Schmidt
Vanderbilt University
43
Douglas C. Schmidt
client
1: method_k()
Wrapper
Facade
method_1()
...
method_m()
2: function_k()
Functions
function_1()
...
function_n()
POSA2 (www.cs.wustl.edu/
schmidt/POSA/)
Forces Resolved
Avoid tedious, error-prone, and non-portable system APIs
Create cohesive abstractions
Vanderbilt University
44
Do
1: PASSIVE
ROLE
ROLE
socket()
bind()
(optional)
connect()
send()/recv()
close()
CLIENT
3: SERVICE
PROCESSING
NETWORK
socket()
bind()
listen()
accept()
send()/recv()
close()
SERVER
Vanderbilt University
Douglas C. Schmidt
46
Douglas C. Schmidt
Broadcasting/multicasting
Passing open file handles
Urgent data delivery and reception
Asynch I/O, non-blocking I/O, I/O-based and timer-based event
multiplexing
Vanderbilt University
47
Douglas C. Schmidt
Header files
Error numbers
Handle vs. descriptor types
Shutdown semantics
I/O controls and socket options
Vanderbilt University
48
49
Douglas C. Schmidt
Vanderbilt University
Non-portable
Limitations
socket()
bind()
connect()
listen()
accept()
read()
write()
readv()
writev()
recv()
send()
recvfrom()
sendto()
recvmsg()
sendmsg()
setsockopt()
getsockopt()
getpeername()
getsockname()
gethostbyname()
getservbyname()
Do
DATA
GRAM
N/
IO ON
T
C
TI
NE ICA
IVE
N
S
N
S
CO MU LE
PA
M
O
R
ER
CO
XF
E
TIV
C
A
STREAM CONNECTED
DATAGRAM
Socket Taxonomy
COMMUNICATION DOMAIN
LOCAL/REMOTE
LOCAL
socket(PF_UNIX)/bind()
sendto()/recvfrom()
socket(PF_UNIX)/bind()
socket(PF_INET)/bind()
sendto()/recvfrom()
socket(PF_INET)/bind()
socket(PF_UNIX)
socket(PF_INET)
bind()/connect()
bind()/connect()
send()/recv()
send()/recv()
socket(PF_UNIX)
socket(PF_INET)
bind()/connect()
bind()/connect()
socket(PF_UNIX)
bind()/listen()/accept()
send()/recv()
socket(PF_UNIX)
bind()/connect()
socket(PF_INET)
bind()/listen()/accept()
send()/recv()
socket(PF_INET)
bind()/connect()
Do
N/ N
O
I
CT ATIO
E
N
IC
IVE
N
S
N
CO MU LE
AS
P
O
M
R
ER
CO
XF
IVE
T
AC
m
gra
D
K_
C
O
LS
DATA
GRAM
CONNECTED
DATAGRAM
STREAM
LOCAL
ram
g
D
K_
C
SO
SOCK_Dgram_Bcast
SOCK_Dgram_Mcast
SOCK_Dgram
LSOCK_Dgram
LSOCK_CODgram
SOCK_CODgram
LSOCK_Acceptor
LSOCK_Stream
LSOCK_Connector
SOCK_Acceptor
SOCK_Stream
SOCK_Connector
Vanderbilt University
Do
ACE_SOCK_IO
ACE_SOCK
ACE_SOCK_Acceptor
ACE_SOCK_Stream
ACE_Addr
ACE_INET_Addr
ACE_SOCK_Connector
Participants
Vanderbilt University
Douglas C. Schmidt
Vanderbilt University
class ACE_SOCK_Acceptor
: public ACE_SOCK
{
public:
// Traits
typedef ACE_INET_Addr PEER_ADDR;
typedef ACE_SOCK_Stream PEER_STREAM;
53
Douglas C. Schmidt
Vanderbilt University
class ACE_INET_Addr
: public ACE_Addr
{
public:
ACE_INET_Addr (u_short port,
const char host[]);
u_short get_port_number (void);
ACE_UINT_32 get_ip_addr (void);
// ...
};
54
Douglas C. Schmidt
55
Do
Do
Douglas C. Schmidt
SOCK
SAP
TLI
SAP
SPIPE
SAP
SSL
SAP
FIFO
SAP
MEM
SAP
SysV
IPC
SOCKET
TLI
STREAM
SSL
NAMED
MMAP
SYSTEM V
API
API
PIPE API
API
PIPE API
API
IPC API
C++NPv1 (www.cs.wustl.edu/schmidt/ACE/book1/)
Vanderbilt University
58
Do
Vanderbilt University
Do
Do
Vanderbilt University
Do
Vanderbilt University
Do
OO Client Logging
Daemon Implementation
int main (int argc, char *argv[])
{
ACE_SOCK_Stream stream;
ACE_SOCK_Connector con;
// Establish connection.
con.connect (stream, ACE_INET_Addr (argc > 1
? atoi (argv[1]) : PORT));
ACE_Log_Record lr;
// Loop forever performing client
// logging daemon processing.
for (;;) {
// ... get logging records from client
//
application processes ...
ACE_UINT_32 size = lr.size;
lr.size = htonl (lr.size);
encode_log_record (&lr);
iovec iov[2];
iov[0].iov_len = sizeof (ACE_UINT_32);
iov[0].iov_base = &lr.size;
iov[1].iov_len = size;
iov[1].iov_base = &lr;
// Uses writev(2);
stream.sendv_n (iov, 2);
}
}
Vanderbilt University
Douglas C. Schmidt
Liabilities
More concise
More robust
More portable
More maintainable
More efficient
Vanderbilt University
64
Douglas C. Schmidt
65
Douglas C. Schmidt
Vanderbilt University
66
Douglas C. Schmidt
Vanderbilt University
67
Douglas C. Schmidt
Vanderbilt University
68
Do
Douglas C. Schmidt
Vanderbilt University
70
Douglas C. Schmidt
ACE
SOCK
ACE
SOCK
Dgram
Bcast
ACE
SOCK
Dgram
ACE
SOCK
CODgram
ACE
SOCK
Stream
ACE
SOCK
Connector
ACE
SOCK
Acceptor
ACE
SOCK
Dgram
Mcast
ACE
LSOCK
Dgram
ACE
LSOCK
CODgram
ACE
LSOCK
Stream
ACE
LSOCK
Connector
ACE
LSOCK
Acceptor
GROUP
DATAGRAM
COMM
COMM
Vanderbilt University
ACE
LSOCK
STREAM
CONNECTION
COMM
ESTABLISHMENT
71
Douglas C. Schmidt
DISTRIBUTED
APPLICATION2
APPLICATION2
DISTRIBUTED
APPLICATION3
APPLICATION3
COMMON INTERFACE
(PARAMETERIZED TYPES)
SOCK_SAP
SOCKET
BSD
SOCKET
API
API
TLI_SAP
BSD
SOCKET
SYSTEM
V
TLIAPIAPI
OS KERNEL
PROTOCOL MECHANISMS
(TCP/IP, OSI, ETC.)
NETWORK
INTERFACE
USER
SPACE
KERNEL
SPACE
72
Douglas C. Schmidt
Vanderbilt University
73
Douglas C. Schmidt
74
Douglas C. Schmidt
Solution
75
Douglas C. Schmidt
handlers
1
Handle
select (handles);
foreach h in handles loop
table[h].handle_event(type)
end loop
N
owns
Event Handler
handle_event(type)
get_handle()
notifies
Synchronous Event
Demultiplexer
select()
Concrete
Event
Handler
www.cs.wustl.edu/schmidt/
POSA/
Intent
Demuxes & dispatches
requests that are
delievered concurrency
to an application by one
or more clients
Forces Resolved
Serially demux events
synchronously &
efficiently
Extend applications
without changing
demuxing code
Vanderbilt University
76
Douglas C. Schmidt
INITIALIZATION
MODE
INITIALIZE
callback :
main
Reactor
Concrete
program Event_Handler
Reactor()
REGISTER HANDLER
EXTRACT HANDLE
START EVENT LOOP
EVENT HANDLING
MODE
FOREACH EVENT DO
DATA ARRIVES
OK TO SEND
SIGNAL ARRIVES
TIMER EXPIRES
REMOVE HANDLER
CLEANUP
Vanderbilt University
register_handler(callback)
get_handle()
handle_events()
select()
handle_input()
handle_output()
handle_signal()
handle_timeout()
Note inversion of
control
Also note how
long-running
event handlers
can degrade
quality of service
since callbacks
steal Reactors
thread of
control...
remove_handler(callback)
handle_close()
77
Do
ACE_Event_Handler
0..1
ACE_Reactor
Application Event
Handler
ACE_Time_Value
ACE_Reactor
ACE_Reactor_Impl
ACE_WFMO_Reactor
TOKEN
ACE_Select_Reactor_Impl
ACE_Select_Reactor_T
bind
<ACE_Select_Reactor_Token>
ACE_TP_Reactor
Vanderbilt University
ACE_Select_Reactor
Do
REGISTERED
OBJECTS 2: sh = new Logging_Handler
:
Logging
3: accept (sh->peer())
: Logging
Handler
4: sh->open()
Handler
: Logging
:
Event
Acceptor
: Event
5: handle_input()
Handler
Handler
6: recv(msg)
: Event
7:process(msg)
Handler
1: handle_input()
: Handle
Table
:Timer
Queue
KERNEL
LEVEL
FRAMEWORK
LEVEL
APPLICATION
LEVEL
: Reactor
Benefits
Liabilities
Straightforward to
program
Concurrency control
is easy
Vanderbilt University
Cant leverage
multi-processors
Douglas C. Schmidt
80
Do
peer_stream_
open()
Svc Handler
Acceptor
ACTIVATES
peer_acceptor_
accept()
APPLICATIONDEFINED
APPLICATIONINDEPENDENT
Reactor
www.cs.wustl.edu/schmidt/POSA/
Intent of Acceptor Role Forces resolved
Reuse passive
Decouple the passive
connection setup
connection and
and service
initialization of a peer
initialization code
service in a distributed
system from the
Ensure that
processing performed
acceptor-mode
once the peer service is handles arent used
connected and
to read/write data
initialized
Vanderbilt University
Do
ACE_Event_Handler
SVC_HANDLER,
PEER_CONNECTOR
ACE_Task
ACE_Connector
PEER_STREAM,
SYNCH_STRATEGY
SVC_HANDLER,
PEER_ACCEPTOR
ACE_Svc_Handler
ACE_Acceptor
bind
Application
Service
Framework characteristics
Uses C++ parameterized types to strategize IPC
and service aspects
Uses Template Method pattern to strategize
creation, connection establishment, and
concurrency policies
Vanderbilt University
Do
: Logging
Acceptor
: Acceptor
: Logging
Handler
: Logging
Handler
: Svc
Handler
: Svc
Handler
PASSIVE
ACTIVE
LISTENER
CONNECTIONS
1: handle_input()
2: sh = make_svc_handler()
3: accept_svc_handler(sh)
4: activate_svc_handler(sh)
: Reactor
: Logging
Handler
: Svc
Handler
: Logging
Handler
: Svc
Handler
Do
Vanderbilt University
Vanderbilt University
Do
Douglas C. Schmidt
Concrete
Class
primitive_operation1()
primitive_operation2()
Vanderbilt University
Intent
...
primitive_operation1()
...
primitive_operation2()
...
86
Douglas C. Schmidt
Acceptor
handle_input()
make_svc_handler()
accept_svc_handler()
activate_svc_handler()
My
Acceptor
make_svc_handler()
activate_svc_handler()
Vanderbilt University
...
make_svc_handler()
...
accept_svc_handler()
...
activate_svc_handler()
Straightforward to
program via inheritance
and dynamic binding
Liabilities
Design is brittle and
can cause explosion of
subclasses due to
whitebox design
87
Douglas C. Schmidt
Context
Strategy
algorithm_interface()
context_interface()
Concrete
Strategy A
Concrete
Strategy C
algorithm_interface()
algorithm_interface()
Define a family of
algorithms, encapsulate
each one, and make
them interchangeable
Concrete
Strategy B
algorithm_interface()
Vanderbilt University
88
Douglas C. Schmidt
<<delegates>>
handle_input()
2: activate_svc_handler(sh)
sh = create_svc_handler ()
...
accept_svc_handler (sh)
...
1: activate_svc_handler(sh)
...
Vanderbilt University
Reactive
Strategy
Concurrency
Strategy
activate_svc_handler()
Thread
Strategy
Process
Strategy
Benefits
More
extensible due
to blackbox
design
Liabilities
More complex
and harder to
develop initially
89
Do
Vanderbilt University
ACE_Acceptor Initialization
Implementation
Note how the PEER_ACCEPTORs open() method
hides all the details associated with passively
initializing communication endpoints
// Initialization.
template <class SH, class PA> int
ACE_Acceptor<SH, PA>::open
(typename const PA::PEER_ADDR &addr,
ACE_Reactor *reactor)
{
// Forward initialization to the concrete
// peer acceptor.
peer_acceptor_.open (addr);
// Register with Reactor.
reactor->register_handler
(this, ACE_Event_Handler::ACCEPT_MASK);
}
Vanderbilt University
Do
Vanderbilt University
Do
Douglas C. Schmidt
ACE_Svc_Handler Implementation
By default, a
ACE_Svc_Handler
object is registered
template <class PS, class SS>
with the singleton
ACE_Svc_Handler<PS, SS>::ACE_Svc_Handler
(ACE_Reactor *r): ACE_Service_Object (r) ACE_Reactor
#define PS PEER_STREAM
#define SS SYNCH_STRAT
{}
template <class PS, class SS>
int ACE_Svc_Handler<PS, SS>::open
(void *) {
// Enable non-blocking I/O.
peer ().enable (ACE_NONBLOCK);
// Register handler with the Reactor.
reactor ()->register_handler
(this, ACE_Event_Handler::READ_MASK);
Vanderbilt University
93
Do
Service
Config
Logging
Acceptor
Logging
Handler
Logging
Handler
LOGGING
RECORDS
CONNECTION
REQUEST
Service
Repository
Service
Manager
Reactor
SERVER
REMOTE
CONTROL
OPERATIONS
CLIENT
CLIENT
Vanderbilt University
CLIENT
CLIENT
Vanderbilt University
Do
Douglas C. Schmidt
Vanderbilt University
96
Douglas C. Schmidt
Vanderbilt University
code
97
Logging_Acceptor Initialization
and Termination
// Automatically called when a Logging_Acceptor
// object is linked dynamically.
Logging_Acceptor::init (int argc, char *argv[])
{
ACE_Get_Opt get_opt (argc, argv, "p:", 0);
ACE_INET_Addr addr (DEFAULT_PORT);
for (int c; (c = get_opt ()) != -1; )
switch (c) {
case p:
addr.set (atoi (getopt.optarg));
break;
default:
break;
}
// Initialize endpoint and register
// with the <ACE_Reactor>.
open (addr, ACE_Reactor::instance ());
}
// Automatically called when object is unlinked.
Logging_Acceptor::fini (void) { handle_close (); }
Vanderbilt University
Do
Douglas C. Schmidt
99
Douglas C. Schmidt
REACTIVE
LAYER
CONFIGURATION
LAYER
APPLICATION
LAYER
Concrete
Component
Component
Config
Component
suspend()
resume()
init()
A
fini()
info()
Event
Handler n
Vanderbilt University
n
1
Component
Repository
Reactor
Decouples the
implementation of services
from the time when they are
configured
Forces Resolved
Reduce resource utilization
Support dynamic
(re)configuration
www.cs.wustl.edu/
schmidt/POSA/
100
Do
ACE_Service_Config
ACE_Service_Object
ACE_Service_Repository
Application Service
ACE_Service_Repository_Iterator
Framework characteristics
ACE_Service_Config uses a variant of the
Monostate pattern
Can be accessed either via a script or
programmatically
Vanderbilt University
Do
SERVICE
CONFIGURATOR
RUNTIME
Service
Repository
Service
Config
svc.conf
FILE
Reactive
Logger
Service
Object
DLLS
Reactor
Service
Object
Thread
Pool
Logger
Service
Object
Douglas C. Schmidt
Vanderbilt University
103
Douglas C. Schmidt
Service Configuration
The logging service is configured Generic event-loop to
dynamically configure service
via scripting in a svc.conf file:
daemons
% cat ./svc.conf
# Dynamically configure
int main (int argc, char *argv[])
# the logging service
{
dynamic Logger
// Initialize the daemon and
Service_Object *
// configure services
logger:_make_Logger() "-p 2001" ACE_Service_Config::open (argc,
# Note, .dll or .so suffix
argv);
# added to the logger
// Run forever, performing the
# automatically
// configured services
ACE_Reactor::instance ()->
run_reactor_event_loop ();
/* NOTREACHED */
}
Vanderbilt University
104
Douglas C. Schmidt
SHUTDOWN/
Service_Config::close()
AWAITING
EVENTS
RECONFIGURE/
Service_Config::process_directives()
NETWORK EVENT/
Reactor::dispatch()
PERFORM
CALLBACK
CALL HANDLER/
Event_Handler::handle_input()
Vanderbilt University
105
Douglas C. Schmidt
106
Douglas C. Schmidt
Vanderbilt University
107
Do
Concurrent OO Logging
Server Architecture
LOGGING SERVER
SERVER
1: SOCK
Acceptor
2: accept()
4: handle_input()
5: spawn()
Logging
Acceptor
Reactor
7: recv() 7: recv()
8: write() 8: write()
Logging
Handler
3: connect()
CLIENT
A
Logging
Handler
6: send()
6: send()
NETWORK
CLIENT
B
Vanderbilt University
Douglas C. Schmidt
Vanderbilt University
109
Douglas C. Schmidt
Concurrency Overview
SHARED ADDRESS SPACE
THREADS
A thread is a sequence of
instructions executed in one
or more processes
One process !
stand-alone systems
More than one process !
distributed systems
PROCESS
110
Douglas C. Schmidt
111
Douglas C. Schmidt
112
Douglas C. Schmidt
Modern OS Concurrency
Modern OS platforms typically provide a standard set of APIs that
handle
Vanderbilt University
113
Douglas C. Schmidt
Lightweight Concurrency
Modern operating systems provide lightweight mechanisms that
manage and synchronize multiple threads within a process
114
Do
THREAD
BLOCKED
USER
KERNEL
REQUEST
USER
KERNEL
CLIENT
CLIENT
SERVER
SERVICE
EXECUTES
RESPONSE
REQUEST
USER
KERNEL
USER
KERNEL
SINGLETHREADED RPC
SERVER
SERVICE
EXECUTES
RESPONSE
RESPONSE
CLIENT
Vanderbilt University
MULTITHREADED RPC
USER
KERNEL
REQUEST
SERVER
SERVICE
EXECUTES
Douglas C. Schmidt
KERNEL-LEVEL
USER-LEVEL
LWP
LWP
PE
PE
PE
LWP
PE
LWP
PE
LWP
PE
PE
THREAD
Vanderbilt University
LWP
PROCESSING
ELEMENT
LIGHTWEIGHT
PROCESS
PE
1. Application
threads
2. Lightweight
processes
3. Kernel threads
4. Processing
elements
SHARED MEMORY
PE
LWP
UNIX
PROCESS
116
Douglas C. Schmidt
Application Threads
Most process resources are
Each thread also contains unique
equally accessible to all threads information, e.g.,
in a process, e.g.,
Identifier
Virtual memory
Register set (e.g., PC and SP)
User permissions and access
Run-time stack
control privileges
Signal mask
Open files
Priority
Signal handlers
Thread-specific data (e.g.,
errno)
Note, there is no MMU protection for threads in a single process
Vanderbilt University
117
Douglas C. Schmidt
Vanderbilt University
118
Douglas C. Schmidt
Vanderbilt University
119
Douglas C. Schmidt
120
Douglas C. Schmidt
121
Do
Process
Manager
ADVANCED SYNCH
Token
Barrier
ACTIVE
OBJECTS
SYNCH
Task
Null
Condition
Thread
MUTEX
LOCK
TYPE
Atomic
Op
TYPE
GUARDS
RW
Mutex
Null
Mutex
Thread
Mutex
Process
Mutex
Condition
TSS
SYNCH WRAPPERS
Mutex
CONDITIONS
Events
File
Lock
Semaphore
Guard
Read
Guard
Thread
Semaphore
Process
Semaphore
Write
Guard
Vanderbilt University
Douglas C. Schmidt
Vanderbilt University
123
Do
loop {
m = act_list.dequeue()
if (m.guard()) m.call()
else act_list.enqueue (m);
1: enqueue(new M1) }
3: dispatch()
Scheduler
dispatch()
enqueue()
VISIBLE
TO
CLIENTS
enqueue()
2: enqueue(M1) dequeue()
1
n
Servant
HIDDEN
FROM
CLIENTS
m1()
m2()
m3()
Activation
List
Method
Request
guard()
4: m1() call()
M1
M2
M3
www.cs.wustl.edu/schmidt/POSA/
Intent
Forces Resolved
Decouples method
execution from method
invocation to enhance
concurrency and simplify
synchronized access to
an object that resides in
its own thread of control
Allow blocking
operations
Vanderbilt University
Permit flexible
concurrency
strategies
Do
2: enqueue (msg)
: TASK
STATE
3: svc ()
4: dequeue (msg)
5: do_work(msg)
: Message
Queue
ACTIVE
1: put (msg)
t1 :
Task
6: put (msg)
t3 :
Task
: TASK
STATE
: Message
Queue
: TASK
STATE
: Message
Queue
ACTIVE
ACTIVE
Vanderbilt University
Douglas C. Schmidt
Vanderbilt University
126
Do
ACE_Service_Object
0..1
SYNCH
ACE_Task
ACE_Thread_Manager
SYNCH
ACE_Message_Block
ACE_Message_Queue
*
Framework characteristics
1. ACE_Tasks can register with an ACE_Reactor
2. They can be dynamically linked
3. They can queue data
4. They can run as active objects in 1 or more
threads
Vanderbilt University
Douglas C. Schmidt
Vanderbilt University
128
Douglas C. Schmidt
129
Douglas C. Schmidt
Vanderbilt University
130
Douglas C. Schmidt
Vanderbilt University
131
Douglas C. Schmidt
Vanderbilt University
132
Douglas C. Schmidt
133
Do
CONNECTIONORIENTED
COMPONENTS
APPLICATIONSPECIFIC
COMPONENTS
Thr
Logging
Acceptor
<<activates>>
SOCK_Stream
NULL_Synch
n Thr
Logging
Handler
SVC_HANDLER
PEER_ACCEPTOR
Svc
Handler
Acceptor
ACE
FRAMEWORK
COMPONENTS
PEER
ACCEPTOR
PEER
STREAM
Connection
Stream
IPC_SAP
Service
Configurator
Concurrency
global
Vanderbilt University
PEER_STREAM
SYNCH
Reactor
Thr_Logging_Acceptor and
Thr_Logging_Handler Interfaces
Template classes that create, connect, and activate
a new thread to handle each client
class Thr_Logging_Handler
: public Logging_Handler
// Inherits <handle_input>
{
public:
// Override definition in <ACE_Svc_Handler>
// class to spawn a new thread! This method
// is called by the <ACE_Acceptor>.
virtual int open (void *);
// Process remote logging records.
virtual int svc (void);
};
class Thr_Logging_Acceptor : public
ACE_Acceptor<Thr_Logging_Handler,
ACE_SOCK_Acceptor>
{
// Same as <Logging_Acceptor>...
};
Vanderbilt University
Do
Thr_Logging_Handler
Implementation
Override definition in the ACE_Svc_Handler class
to spawn a new thread
int
Thr_Logging_Handler::open (void *)
{
// Spawn a new thread to handle
// logging records with the client.
activate (THR_DETACHED);
}
Vanderbilt University
Do
Douglas C. Schmidt
extern "C"
% cat ./svc.conf
ACE_Service_Object *make_Logger (void);
# Dynamically reconfigure
# the logging service
ACE_Service_Object *
remove Logger
make_Logger (void)
dynamic Logger
{
Service_Object *
return new Thr_Logging_Acceptor;
thr_logger:_make_Logger()
}
"-p 2002"
# .dll or .so suffix added to
# "thr_logger" automatically
137
Douglas C. Schmidt
Vanderbilt University
138
Douglas C. Schmidt
139
Douglas C. Schmidt
140
Do
Solution: Synchronization
Wrapper Facades
class ACE_Thread_Mutex
{
public:
ACE_Thread_Mutex (void) {
mutex_init (&lock_, USYNCH_THREAD, 0);
}
ACE_Thread_Mutex (void) { mutex_destroy (&lock_);
int acquire (void) { return mutex_lock (&lock_); }
int tryacquire (void)
{ return mutex_trylock (&lock_); }
int release (void) { return mutex_unlock (&lock_);
private:
// SunOS 5.x serialization mechanism.
mutex_t lock_;
void operator= (const ACE_Thread_Mutex &);
ACE_Thread_Mutex (const ACE_Thread_Mutex &);
};
Vanderbilt University
Porting ACE_Thread_Mutex to
Windows NT
class ACE_Thread_Mutex
{
public:
ACE_Thread_Mutex (void) {
lock_ = CreateMutex (0, FALSE, 0);
}
ACE_Thread_Mutex (void) {
CloseHandle (lock_);
}
int acquire (void) {
return WaitForSingleObject (lock_, INFINITE);
}
int tryacquire (void) {
return WaitForSingleObject (lock_, 0);
}
int release (void) {
return ReleaseMutex (lock_);
}
private:
ACE_HANDLE lock_; // Windows locking mechanism.
// ...
Vanderbilt University
Do
Douglas C. Schmidt
www.cs.wustl.edu/schmidt/PDF/ObjMan.pdf
Vanderbilt University
143
Douglas C. Schmidt
144
Douglas C. Schmidt
#define ACE_GUARD(MUTEX,OB,LOCK) \
ACE_Guard<MUTEX> OB (LOCK); if (OB.locked () == 0) return;
#define ACE_GUARD_RETURN(MUTEX,OB,LOCK,RET) \
ACE_Guard<MUTEX> OB (LOCK); if (OB.locked () == 0) return RET;
#define ACE_WRITE_GUARD(MUTEX,OB,LOCK) \
ACE_Write_Guard<MUTEX> OB (LOCK); if (OB.locked () == 0) return;
#define ACE_WRITE_GUARD_RETURN(MUTEX,OB,LOCK,RET) \
ACE_Write_Guard<MUTEX> OB (LOCK); if (OB.locked () == 0) return RET;
#define ACE_READ_GUARD(MUTEX,OB,LOCK) \
ACE_Read_Guard<MUTEX> OB (LOCK); if (OB.locked () == 0) return;
#define ACE_READ_GUARD_RETURN(MUTEX,OB,LOCK,RET) \
ACE_Read_Guard<MUTEX> OB (LOCK); if (OB.locked () == 0) return RET;
Vanderbilt University
145
Do
Thread-safe handle_log_record()
Function
template <class LOCK = ACE_Thread_Mutex> ssize_t
handle_log_record (ACE_HANDLE in, ACE_HANDLE out) {
// beware static initialization...
static LOCK lock;
ACE_UINT_32 len;
ACE_Log_Record lr;
// The first recv reads the length (stored as a
// fixed-size integer) of adjacent logging record.
ssize_t n = s.recv_n ((char *) &len, sizeof len);
if (n <= 0) return n;
len = ntohl (len); // Convert byte-ordering
// Perform sanity check!
if (len > sizeof (lr)) return -1;
// The second recv then reads <len> bytes to
// obtain the actual record.
s.recv_n ((char *) &lr, sizeof lr);
// Decode and print record.
decode_log_record (&lr);
// Automatically acquire mutex lock.
ACE_GUARD_RETURN (LOCK, guard, lock, -1);
if (ACE_OS::write (out, lr.buf, lr.size) == -1)
return -1; // Automatically release mutex lock.
return 0;
}
Vanderbilt University
Douglas C. Schmidt
147
Douglas C. Schmidt
1: request ()
Adapter
client
request()
Adaptee1
Adaptee2
specific_request()
2: specific_request()
specific_request()
Adaptee3
specific_request()
Vanderbilt University
Force resolved:
Provide an interface
that captures
similarities between
different OS
mechanisms, e.g.,
locking or IPC
148
Douglas C. Schmidt
Remaining Caveats
int Logging_Handler::handle_input (void)
{
ssize_t n = handle_log_record
(peer ().get_handle (), ACE_STDOUT);
if (n > 0)
// Count # of logging records.
++request_count;
// Danger, race condition!!!
return n <= 0 ? -1 : 0;
}
There is a race
condition when
incrementing the
request_count
variable
Solving this problem
using the
ACE_Thread_Mutex
or ACE_Guard classes
is still tedious,
low-level, and
error-prone
149
Do
Transparently Parameterizing
Synchronization Using C++
Use the Strategized Locking pattern, C++
templates, and operator overloading to define
atomic operators
template <class LOCK = ACE_Thread_Mutex,
class TYPE = u_long>
class ACE_Atomic_Op {
public:
ACE_Atomic_Op (TYPE c = 0) { count_ = c; }
TYPE operator++ (void) {
ACE_GUARD (LOCK, guard, lock_); return ++count_;
}
operator TYPE () {
ACE_GUARD (LOCK, guard, lock_); return count_;
}
// Other arithmetic operations omitted...
private:
LOCK lock_;
TYPE count_;
};
Vanderbilt University
Douglas C. Schmidt
Vanderbilt University
151
Douglas C. Schmidt
Vanderbilt University
152
Do
1: GET ~schmidt
HTTP/1.0
2: index.html
WWW
SERVER
PROTOCOL
HANDLERS
HTML
PARSER
GUI
DISPATCHER
REQUESTER
GRAPHICS
ADAPTER
COMMUNICATION PROTOCOL
(E.G., HTTP)
OS KERNEL
OS KERNEL
OS I/O SUBSYSTEM
OS I/O SUBSYSTEM
NETWORK ADAPTERS
NETWORK ADAPTERS
NETWORK
www.cs.wustl.edu/jxh/research/
Vanderbilt University
Vanderbilt University
Do
Douglas C. Schmidt
Drawbacks
155
Do
Vanderbilt University
Vanderbilt University
Do
Vanderbilt University
Do
Douglas C. Schmidt
Vanderbilt University
159
Douglas C. Schmidt
Vanderbilt University
160
Douglas C. Schmidt
161
Douglas C. Schmidt
Monitor Object
+ synchronized_method_1()
...
+ synchronized_method_m()
# monitor_lock_
# monotor_condition_1_
...
# monitor_condition_n_
schmidt/POSA/
Forces Resolved
Synchronization corresponds to methods
Objects, not clients, are responsible for synchronization
Cooperative method scheduling
Vanderbilt University
162
Douglas C. Schmidt
Vanderbilt University
163
Douglas C. Schmidt
// synchronized
void acquire_resources (void) {
// synchronized
// Automatically acquire lock.
void release_resources (void) {
ACE_GUARD (ACE_Thread_Mutex, g, lock); // Automatically acquire lock.
ACE_GUARD (ACE_Thread_Mutex, g, lock);
// Check condition in loop
while (condition expression false)
// Atomically modify shared
// Sleep.
// information...
cond.wait ();
cond.signal ();
// Atomically modify shared
// Could use cond.broadcast() here.
// information.
// guard automatically
// Destructor releases lock.
// releases lock.
}
}
Vanderbilt University
164
Douglas C. Schmidt
Vanderbilt University
165
Douglas C. Schmidt
Message
Block
Message
Queue
next()
prev()
cont()
head_
tail_
Data_Block
Message
Block
Message
Block
next()
prev()
cont()
next()
prev()
cont()
Data_Block
Data_Block
Message
Block
next()
prev()
cont()
Data_Block
Vanderbilt University
An ACE_Message_Queue is a list of
ACE_Message_Blocks
Do
rd_ptr_ : size_t
wr_ptr_ : size_t
cont_ : ACE_Message_Block *
next_ : ACE_Message_Block *
prev_ : ACE_Message_Block *
data_block_ : ACE_Data_Block *
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
ACE_Data_Block
# base_ : char *
# refcnt_ : int
Class characteristics
Hide messaging implementations from clients
ACE_Message
_Block
cont()
data_block()
wr_ptr()
rd_ptr()
ACE_Data
_Block
PAYLOAD
(1) SIMPLE MESSAGE STRUCTURE
Vanderbilt University
ACE_Message
_Block
cont()
data_block()
wr_ptr()
rd_ptr()
ACE_Message
_Block
cont()
data_block()
rd_ptr()
wr_ptr()
ACE_Data_Block
reference_count() = 2
Do
ACE_Message_Queue
#
#
#
#
head_ : ACE_Message_Block *
tail_ : ACE_Message_Block *
high_water_mark_ : size_t
low_water_mark_ : size_t
Class characteristics
Note how the synchronization aspect can be
strategized!
Vanderbilt University
Do
Vanderbilt University
Douglas C. Schmidt
170
Do
high_water_mark_;
low_water_mark_;
cur_bytes_;
cur_count_;
Vanderbilt University
Douglas C. Schmidt
172
ACE_Message_Queue Class
Implementation
template <class SYNCH_STRAT>
ACE_Message_Queue<SYNCH_STRAT>::ACE_Message_Queue
(size_t hwm, size_t lwm)
: not_empty_cond_ (lock_), not_full_cond_ (lock_),
... {}
template <class SYNCH_STRAT> int
ACE_Message_Queue<SYNCH_STRAT>::is_empty_i (void) const
{ return cur_bytes_ == 0 && cur_count_ == 0; }
template <class SYNCH_STRAT> int
ACE_Message_Queue<SYNCH_STRAT>::is_full_i (void) const
{ return cur_bytes_ > high_water_mark_; }
template <class SYNCH_STRAT> int
ACE_Message_Queue<SYNCH_STRAT>::is_empty (void) const
{
ACE_GUARD_RETURN (SYNCH_STRAT::MUTEX, g, lock_, -1);
return is_empty_i ();
}
template <class SYNCH_STRAT> int
ACE_Message_Queue<SYNCH_STRAT>::is_full (void) const
{
ACE_GUARD_RETURN (SYNCH_STRAT::MUTEX, g, lock_, -1);
return is_full_i ();
}
Vanderbilt University
Do
Douglas C. Schmidt
ACE_Message_Queue Operations
template <class SYNCH_STRAT> int
template <class SYNCH_STRAT> int
ACE_Message_Queue<SYNCH_STRAT>::
ACE_Message_Queue<SYNCH_STRAT>::
enqueue_tail (ACE_Message_Block *item, dequeue_head (ACE_Message_Block *&item,
ACE_Time_Value *tv) {
ACE_Time_Value *tv) {
ACE_GUARD_RETURN (SYNCH_STRAT::MUTEX, ACE_GUARD_RETURN (SYNCH_STRAT::MUTEX,
guard, lock_, -1);
guard, lock_, -1);
// Wait while the queue is empty.
// Wait while the queue is full.
while (is_empty_i ()) {
while (is_full_i ()) {
// Release lock_ and wait for timeout,
// Release the <lock_> and wait
// signal, or a new message being
// for timeout, signal, or space
// placed in the list.
// to become available in the list.
if (not_empty_cond_.wait (tv) == -1)
if (not_full_cond_.wait (tv) == -1)
return -1;
return -1;
}
}
// Actually dequeue the first message.
// Actually enqueue the message at
dequeue_head_i (item);
// the end of the list.
enqueue_tail_i (item);
// Tell blocked threads that list
// is no longer full.
// Tell blocked threads that
if (cur_bytes_ <= low_water_mark_)
// list has a new item!
not_full_cond_.signal ();
not_empty_cond_.signal ();
}
}
Vanderbilt University
174
Douglas C. Schmidt
175
Douglas C. Schmidt
Vanderbilt University
176
Douglas C. Schmidt
Reactive
Thread-per-request
Thread-per-connection
Synchronous Thread Pool
Leader/Followers Thread Pool
Half-Sync/Half-Async Thread Pool
Asynchronous Thread Pool
Vanderbilt University
177
Do
HTTP
Handler
HTTP
Handler
6: PROCESS
HTTP
Acceptor
Reactor
HTTP REQUEST
SERVER
1: CONNECT
CLIENT
CLIENT
Vanderbilt University
CLIENT
Do
2: HANDLE INPUT
3: CREATE HANDLER
4: ACCEPT CONNECTION
5: SPAWN THREAD
HTTP
Handler
6: PROCESS
HTTP
Acceptor
Reactor
HTTP REQUEST
SERVER
1: CONNECT
CLIENT
Vanderbilt University
CLIENT
CLIENT
Do
PER CONNECTION
HTTP
HTTP
Handler Handler HTTP
Handler
2: CREATE, ACCEPT,
AND ACTIVATE
HTTP_HANDLER
HTTP
Acceptor
Reactor
4: PROCESS
HTTP REQUEST
1: HTTP
REQUEST
CLIENT
CLIENT
Vanderbilt University
CLIENT
SERVER
Do
Event
Dispatcher
HTTP
Handler
HTTP
Handler
2: ACCEPT CONNECTION
3: MORPH INTO HANDLER
HTTP
Handler
4: PROCESS
HTTP
Acceptor
HTTP
Acceptor
HTTP REQUEST
1: HTTP
REQUEST
CLIENT
CLIENT
Vanderbilt University
CLIENT
SERVER
Do
Half-Sync/Half-Async Synchronous
Thread Pool Web Server
Active
Object
Message
Queue
2: HANDLE INPUT
3: ENQUEUE REQUEST
4: DEQUEUE &
Active
Object
PROCESS
REQUEST
Active
Object
5: PROCESS
HTTP REQUEST
Active
Object
HTTP
Handler
HTTP
Handler
HTTP
Handler
HTTP
Acceptor
Reactor
1: HTTP
REQUEST
SERVER
CLIENT
CLIENT
Vanderbilt University
CLIENT
Do
HTTP
Handler
6: DEQUEUE COMPLETION
& PROCESS
HTTP
REQUEST
Handler
HTTP
Handler
7: PROCESS
HTTP REQUEST
HTTP
Handler
Accept
Proactor
3: HTTP
REQUEST
SERVER
CLIENT
CLIENT
Vanderbilt University
CLIENT
Do
HTTP
Handler
HTTP
Handler
HTTP
Handler
Sock
Stream
Sock
Stream
Sock
Stream
Event
Dispatcher
HTTP
Acceptor
Sock
Acceptor
Event Dispatcher
Do
Thread-per
Request
Connector
Active
Object
Thread-per
Connection
Asynchronous
Completion
Token
Wrapper
Facade
Acceptor
Half-Sync/
Half-Async
Component
Configurator
Reactor/
Proactor
STRATEGIC PATTERNS
TACTICAL PATTERNS
Strategy
Vanderbilt University
Abstract
Factory
Adapter
Double
Checked
Locking
Singleton
Douglas C. Schmidt
186
Do
svc_run
QUEUEING
LAYER
HTTP
Handler
I/O DEMUXING
LAYER
svc_run
svc_run
Msg
HTTP
Queue
Processor
HTTP
Handler
Reactor
svc_run
Options
HTTP
Handler
HTTP
Acceptor
www.cs.wustl.edu/schmidt/PDF/HPL.pdf
Vanderbilt University
Do
An Integrated Reactive/Active
Web Server
REGISTERED
LEVEL
HTTP
Handler
HTTP
Handler
HTTP
Event Handler
HTTP
HandlerEvent
Processor
HandlerEvent
Handler 2: recv_request(msg)
3: putq(msg)
LEVEL
1: handle_input()
: Handle
Table
: Reactor
OS EVENT DEMULTIPLEXING INTERFACE
LEVEL
KERNEL
FRAMEWORK
APPLICATION
OBJECTS
svc_run
4: getq(msg)
5:svc(msg)
svc_run
svc_run
HTTP
Acceptor
Event
Handler
Douglas C. Schmidt
189
Douglas C. Schmidt
190
Douglas C. Schmidt
Integrating Multi-threading
Problem
Vanderbilt University
191
Do
LEVEL
4: getq(msg)
5:svc(msg)
HTTP
Handler
HTTP
Handler
HTTP
Event Handler
HTTP
Handler
Event
Processor
HandlerEvent
Handler 2: recv_request(msg)
3: putq(msg)
1: handle_input()
LEVEL
svc_run
HTTP
Acceptor
Event
Handler
: Handle
Table
: Reactor
OS EVENT DEMULTIPLEXING INTERFACE
LEVEL
KERNEL
FRAMEWORK
APPLICATION
OBJECTS
svc_run
svc_run
Douglas C. Schmidt
Processes HTTP
requests using the
Thread-Pool
concurrency model
This method
implements the
synchronous task
portion of the HalfSync/Half-Async
pattern
Vanderbilt University
193
Vanderbilt University
Do
Douglas C. Schmidt
Vanderbilt University
195
Douglas C. Schmidt
HTTP
Processor
static instance()
static instance_
Forces Resolved:
Ensures atomic object
initialization
Mutex
www.cs.wustl.edu/
schmidt/POSA/
Vanderbilt University
Intent
Caveat!
This pattern assumes atomic
memory access
196
Douglas C. Schmidt
197
Douglas C. Schmidt
Vanderbilt University
198
Douglas C. Schmidt
TASK LAYER
LAYER
TASK LAYER
SYNCHRONOUS
ASYNCHRONOUS
QUEUEING
SYNC
TASK 3
SYNC
TASK 2
1, 4: read(data)
MESSAGE QUEUES
3: enqueue(data)
ASYNC
TASK
Vanderbilt University
2: interrupt
EXTERNAL
EVENT SOURCES
Intent
Decouples synchronous I/O
from asynchronous I/O in a
system to simplify concurrent
programming effort without
degrading execution efficiency
Forces Resolved:
Simplify programming
Ensure efficient I/O
www.cs.wustl.edu/
schmidt/POSA/
199
Do
svc_run
svc_run
svc_run
4: getq(msg)
5:svc(msg)
QUEUEING
LEVEL
SYNC TASK
LEVEL
HTTP
Processor
ASYNC TASK
LEVEL
HTTP
Handler
HTTP
Handler
HTTP
Event Handler
HandlerEvent
HandlerEvent
Handler
1: handle_input()
2: recv_request(msg)
3: putq(msg)
Vanderbilt University
HTTP
Acceptor
Event
Handler
: Handle
Table
: Reactor
Do
Douglas C. Schmidt
202
Douglas C. Schmidt
Intent
INDEPENDENT
Demultiplexes and
dispatches service
requests that are
triggered by the
completion of
asynchronous
operations
Vanderbilt University
APPLICATIONDEPENDENT
HTTP
Handler
overlapped_result =
GetQueuedCompleteStatus();
overlapped_result->complete()
Completion
Handler
handle_accept()
handle_read_file()
handle_write_file()
handle_timeout()
get_handle() A
n
Proactor
handle_events()
Handles
Async
Write
HTTP
Acceptor
Async
Op
Async
Accept
open()
cancel()
1
Timer_Queue
schedule_timer(h)
cancel_timer(h)
www.cs.wustl.edu/schmidt/POSA/
203
Do
ACE_Proactor
ACE_Service_Handler
ACE_Asynch_Acceptor
ACE_Asynch_Connector
ACE_Handler
ACE_Asynch_Read_Stream
ACE_Asynch_Write_Stream
ACE_Asynch_Result
Framework characteristics
Similar to the ACE Reactor framework, except
behavior is inverse
Portable to Windows and various UNIX
platforms that support aio_*() family of
methods
Vanderbilt University
Do
1: accept
connections
7: create
Acceptor
4: connect
Web
Browser
6:
accept
complete
2: accept
(Acceptor,
Dispatcher)
Completion
Dispatcher
3: handle
events
HTTP
Handler
8: read (Handler,
Dispatcher)
Operating
System
5: accept
complete
1: GET
/etc/passwd
Web
Browser
Web Server
HTTP
Handler
4: parse request
Vanderbilt University
Douglas C. Schmidt
206
Do
: HTTP
Acceptor
: Acceptor
: HTTP
Handler
: HTTP
Handler
: Svc
Handler
: Svc
Handler
PASSIVE
ACTIVE
LISTENER
CONNECTIONS
1: handle_input()
2: sh = make_svc_handler()
3: accept_svc_handler(sh)
4: activate_svc_handler(sh)
: Reactor
: HTTP
Handler
: Svc
Handler
: HTTP
Handler
: Svc
Handler
Vanderbilt University
Douglas C. Schmidt
Vanderbilt University
208
Vanderbilt University
Do
Douglas C. Schmidt
TP Web
Server
RUNTIME
Service
Repository
Service
Config
svc.conf
FILE
Vanderbilt University
Service
Object
Reactor
DLLS
Reactive
Web
Server
Service
Object
TPR
Web
Server
Service
Object
210
Douglas C. Schmidt
% cat ./svc.conf
dynamic Web_Server
Service_Object *
web_server:_make_Web_Server()
"-p 80 -t $THREADS"
# .dll or .so suffix added to
# "web_server" automatically
Vanderbilt University
ACE_Service_Object *
make_Web_Server (void)
{
return new
HTTP_Acceptor<ACE_SOCK_Acceptor>;
// ACE dynamically unlinks and
// deallocates this object.
}
211
Douglas C. Schmidt
Vanderbilt University
The main()
function is totally
generic!
Dynamically
configure & execute
Web Server
Make any
application
Web-enabled
212
Douglas C. Schmidt
Acceptor
Protocol
Filter
Tilde
Expander
~
/home/...
Event Dispatcher
Adapter
Protocol Pipeline
Framework
Streams
Concurrency
Strategy
Framework
Service Configurator
www.cs.wustl.edu/jxh/research/
Vanderbilt University
Strategy
State Singleton
Cached Virtual
Filesystem
Active Object
Strategy
Reactor/Proactor
I/O Strategy
Framework
Use lightweight
concurrency
Minimize locking
Apply file caching
and memory
mapping
Use gather-write
mechanisms
Minimize logging
Pre-compute HTTP
responses
Avoid excessive
time() calls
Optimize the
transport interface
213
Douglas C. Schmidt
TRACKING
STATION
PEERS
STATUS INFO
WIDE AREA
NETWORK
COMMANDS
BULK DATA
TRANSFER
GATEWAY
GROUND
STATION
PEERS
Vanderbilt University
214
Do
OO Software Architecture
of the Gateway
Routing
Table
Consumer
Handler
Supplier
Handler
Reactor
Consumer
Handler
Supplier
Handler
Connector
INCOMING
MESSAGES
Acceptor
OUTGOING
MESSAGES
GATEWAY
CONNECTION
REQUEST
CONNECTION
REQUEST
www.cs.wustl.edu/schmidt/PDF/
TAPOS-00.pdf
All components in this architecture are based on
patterns from ACE
Vanderbilt University
Douglas C. Schmidt
Gateway Behavior
Components in the Gateway behave as follows:
216
Do
Non-blocking
Buffered I/O
Component
Configurator
Half-Sync/
Half-Async
STRATEGIC
PATTERNS
Reactor
TACTICAL
Template Factory Proxy Wrapper
Iterator
PATTERNS
Method Method
Facade
Vanderbilt University
Do
CONNECTIONORIENTED
COMPONENTS
APPLICATIONSPECIFIC
COMPONENTS
1 Proxy
Handler
Connector
<<activates>>
SOCK_Stream
Null_Synch
Supplier/Consumer
n Handler
SVC_HANDLER
PEER_CONNECTOR
Svc
Handler
Connector
ACE
FRAMEWORK
COMPONENTS
PEER
CONNECTOR
PEER
STREAM
Connection
Stream
IPC_SAP
Service
Configurator
Concurrency
global
Vanderbilt University
PEER_STREAM
SYNCH
Reactor
Douglas C. Schmidt
OO Gateway Architecture
Application-specific components
ACE_Svc_Handler
Performs I/O-related tasks with connected clients
ACE_Connector factory
Establishes new connections with clients
Dynamically creates an ACE_Svc_Handler object for each
client and activates it
Application-independent ACE framework components
219
Do
CONCRETE EVENT
HANDLERS
Consumer
Consumer Handler
4: send(msg)
Handler
2: recv(msg)
Event
Event
3: route(msg)
Handler
Handler
Supplier
Handler
Event
Handler
1: handle_input()
Handle
Table
Timer
Queue
KERNEL
LEVEL
FRAMEWORK
LEVEL
APPLICATION
LEVEL
: Reactor
Benefits
Liabilities
Straightforward to
program
Design is brittle
Concurrency control
is trivial
Vanderbilt University
Cant leverage
multi-processors
Douglas C. Schmidt
221
Do
peer_stream_
open()
Svc Handler
Connector
ACTIVATES
connect(sh, addr)
complete()
APPLICATION-
HANDLE ASYNC
DEFINED
CONNECTION COMPLETION
APPLICATIONINDEPENDENT
Reactor
www.cs.wustl.edu/schmidt/POSA/
Intent of Connector Role Forces Resolved:
Decouple the active
Reuse connection
connection and
code
initialization of a peer
Efficiently setup
service in a distributed
connections with
system from the
many peers or over
processing performed
long delay paths
once the peer service is
connected and initialized
Vanderbilt University
Douglas C. Schmidt
ACE_Event_Handler
SVC_HANDLER,
PEER_CONNECTOR
ACE_Task
ACE_Connector
PEER_STREAM,
SYNCH_STRATEGY
SVC_HANDLER,
PEER_ACCEPTOR
ACE_Svc_Handler
ACE_Acceptor
bind
Application
Service
Vanderbilt University
223
Do
Svc
Handler
Hash_Map
Svc
Handler
ACTIVE
CONNECTIONS
Connector
PENDING
CONNECTIONS
Svc
Handler
Svc
Handler
Reactor
Vanderbilt University
Vanderbilt University
Do
Vanderbilt University
Do
Do
ACE_Synch_Options and
ACE_Connector Semantics
Reactor
Yes
Timeout
0,0
Yes
time
Yes
NULL
No
0,0
No
time
No
Behavior
Return
1
with
errno
EWOULDBLOCK;
service handler
is closed via reactor event loop.
Return
1
with
errno
EWOULDBLOCK; wait up to specified
amount of time for completion using
the reactor.
Return
1
with
errno
EWOULDBLOCK; wait for completion
indefinitely using the reactor.
Close service handler directly; return
1 with errno EWOULDBLOCK.
Block in connect_svc_handler()
up to specified amount of time for
completion; if still not completed,
return 1 with errno ETIME.
Block in connect_svc_handler()
indefinitely for completion.
,
,
NULL
Vanderbilt University
Do
Vanderbilt University
Vanderbilt University
Do
Do
Vanderbilt University
Do
Svc
Handler
Proxy
Handler
Consumer
Handler
Message
Queue
Supplier
Handler
ACE_Connector !
ACE_Proxy_Handler_Connector
ACE_Svc_Handler !
ACE_Proxy_Handler !
ACE_Supplier_Handler and
ACE_Consumer_Handler
Vanderbilt University
Do
Douglas C. Schmidt
Vanderbilt University
233
Douglas C. Schmidt
234
Do
Detailed OO Architecture
of the Gateway
Routing
Table
Consumer
Handler
SOCK
Stream
Supplier
Handler
Hash Map
Manager
Message
Queue
SOCK
Stream
Reactor
Supplier
Handler
Connector
SOCK
Stream
SOCK
Connector
INCOMING
MESSAGES
Hash Map
Manager
Acceptor
SOCK
Acceptor
SOCK
Stream
Message
Queue
OUTGOING
MESSAGES
GATEWAY
CONNECTION
REQUEST
Consumer
Handler
CONNECTION
REQUEST
Vanderbilt University
ACE_Supplier_Handler Interface
class Supplier_Handler : public Proxy_Handler
{
public:
Supplier_Handler (void);
protected:
// Receive and process Peer messages.
virtual int handle_input (ACE_HANDLE);
// Receive a message from a Peer.
virtual int recv_peer (ACE_Message_Block *&);
// Action that routes a message from a Peer.
int route_message (ACE_Message_Block *);
// Keep track of message fragment.
ACE_Message_Block *msg_frag_;
};
Vanderbilt University
Do
ACE_Consumer_Handler Interface
class Consumer_Handler : public Proxy_Handler
{
public:
Consumer_Handler (void);
// Send a message to a Gateway
// (may be queued).
virtual int put (ACE_Message_Block *,
ACE_Time_Value * = 0);
protected:
// Perform a non-blocking put().
int nonblk_put (ACE_Message_Block *mb);
// Finish sending a message when
// flow control abates.
virtual int handle_output (ACE_HANDLE);
// Send a message to a Peer.
virtual int send_peer (ACE_Message_Block *);
};
Vanderbilt University
Do
Douglas C. Schmidt
Vanderbilt University
ACE_Proxy_Handler_
Connector is a concrete
factory class that:
Establishes connections with
Peers to produce
ACE_Proxy_Handlers
Activates
ACE_Proxy_Handlers,
which then route messages
ACE_Proxy_Handler_
Connector also ensures
reliability by restarting failed
connections
238
Do
ACE_Proxy_Handler_Connector
Implementation
// (re)initiate a connection to a Proxy_Handler
int
Proxy_Handler_Connector::initiate_connection
(Proxy_Handler *ph)
{
// Use asynchronous connections...
if (connect (ph,
ph->addr (),
ACE_Synch_Options::asynch) == -1) {
if (errno == EWOULDBLOCK)
// No error, were connecting asynchronously.
return -1;
else
// This is a real error, so reschedule
// ourselves to reconnect.
reactor ()->schedule_timer
(ph, 0, ph->timeout ());
}
else // Were connected synchronously!
return 0;
}
Vanderbilt University
Douglas C. Schmidt
Routing
Table
ROUTING
LAYER
find()
Supplier
Handler
REACTIVE
LAYER
handle_input()
Event
Handler n
Message
Queue
n
Consumer
Handler
handle_output()
put()
Reactor
www.cs.wustl.edu/schmidt/PDF/
TAPOS-00.pdf
Vanderbilt University
Forces Resolved:
Keep misbehaving
connections from disrupting
the QoS for well-behaved
connections
Different concurrency
strategies for
Supplier_Handlers and
Consumer_Handlers
240
Do
Collaboration in Single-threaded
Gateway Routing
Consumer
Handler
Routing
Table
Message
Queue
ROUTE
ID
4:
pu
t(
m
sg
)
Consumer
Handlers
3: find()
Supplier
Handler
6: put (msg)
1: handle_input()
2: recv_peer(msg)
5: send_peer(msg)
Consumer
Handler
Message
Queue
7: send_peer(msg)
8: enqueue(msg)
9: schedule_wakeup()
--------------10: handle_output()
11: dequeue(msg)
12: send_peer(msg)
Vanderbilt University
Supplier_Handler and
Consumer_Handler Implementations
int Supplier_Handler::handle_input (ACE_HANDLE) {
ACE_Message_Block *route_addr = 0;
int n = recv_peer (route_addr);
// Try to get the next message.
if (n <= 0) {
if (errno == EWOULDBLOCK) return 0;
else return n;
}
else
route_message (route_addr);
}
// Send a message to a Peer (queue if necessary).
int Consumer_Handler::put (ACE_Message_Block *mb,
ACE_Time_Value *) {
if (msg_queue_->is_empty ())
// Try to send the message *without* blocking!
nonblk_put (mb);
else // Messages are queued due to flow control.
msg_queue_->enqueue_tail
(mb, &ACE_Time_Value::zero);
}
Vanderbilt University
Do
Do
Vanderbilt University
Peer_Message Schema
// Peer address is used to identify the
// source/destination of a Peer message.
class Peer_Addr {
public:
CONN_ID conn_id_; // Unique connection id.
u_char logical_id_; // Logical ID.
u_char payload_; // Payload type.
};
// Fixed sized header.
class Peer_Header { public: /* ... */ };
// Variable-sized message (sdu_ may be
// between 0 and MAX_MSG_SIZE).
class Peer_Message {
public:
// The maximum size of a message.
enum { MAX_PAYLOAD_SIZE = 1024 };
Peer_Header header_; // Fixed-sized header.
char sdu_[MAX_PAYLOAD_SIZE]; // Message payload.
};
Vanderbilt University
Do
Douglas C. Schmidt
Vanderbilt University
245
Do
Vanderbilt University
Douglas C. Schmidt
247
Douglas C. Schmidt
248
Do
Vanderbilt University
Do
Do
Service
Object
Hash Map
Manager
APPLICATIONINDEPENDENT
Proxy
Handler
Connector
Config
Table
SUPPLIER HANDLER
CONSUMER HANDLER
APPLICATIONSPECIFIC
Routing
Table
Gateway
Vanderbilt University
Douglas C. Schmidt
template
<class SUPPLIER_HANDLER,
int main (int argc, char *argv[])
class CONSUMER_HANDLER>
{
class Gateway
// Initialize the daemon and
: public Service_Object
// dynamically configure services.
{
ACE_Service_Config::open (argc,
public:
argv);
// Perform initialization.
// Run forever, performing the
virtual int init
// configured services.
(int argc, char *argv[]);
ACE_Reactor::instance ()->
run_reactor_event_loop ();
// Perform termination.
/* NOTREACHED */
virtual int fini (void);
}
Vanderbilt University
252
Do
Service
Repository
Service
Config
svc.conf
FILE
Reactive
Gateway
Service
Object
Reactor
DLLS
Thread-per
Connection
Gateway
Service
Object
Thread
Pool
Gateway
Service
Object
Vanderbilt University
Douglas C. Schmidt
Vanderbilt University
254
Douglas C. Schmidt
Vanderbilt University
255
Do
Consumer
Consumer Handler
Handler
Event
Handler
Event
Handler
CONCRETE
EVENT
HANDLERS
Supplier
Supplier
Handler
Supplier
Handler
EventHandler
Event
Handler
4: send(msg)
Event
Handler
Handler
2: recv(msg)
3: route(msg)
1: handle_input()
Timer
Queue
KERNEL
LEVEL
FRAMEWORK
LEVEL
APPLICATION
LEVEL
Handle
Table
Signal
Handlers
Reactor
OS EVENT DEMULTIPLEXING INTERFACE
Vanderbilt University
Do
Collaboration in Multi-threaded
Gateway Routing
Consumer
Handler
Routing
Table
3: find()
Consumer
Handlers
Supplier
Handler
4:
pu
t(
m
sg
)
ROUTE
ID
Message
Queue
5: send_peer(msg)
Consumer
Handler
Message
Queue
6: put (msg)
5: send_peer(msg)
1: handle_input()
2: recv_peer(msg)
Vanderbilt University
Douglas C. Schmidt
Consumer
Handler
ASYNCHRONOUS
TASK LAYER
Consumer
Handler
Consumer
Handler
MESSAGE QUEUES
2: recv(msg)
3: get_route(msg)
4: enqueue(msg)
Supplier
Handler Supplier
Supplier
Handler
Handler
Vanderbilt University
1: dequeue(msg)
2: send(msg)
QUEUEING
LAYER
SYNCHRONOUS
TASK LAYER
1: dispatch()
Reactor
258
Do
CONNECTIONORIENTED
COMPONENTS
APPLICATIONSPECIFIC
COMPONENTS
1 Proxy
Handler
Connector
<<activates>>
SOCK_Stream
MT_Synch
Supplier/Thr_Consumer
Handler
n
SVC_HANDLER
PEER_CONNECTOR
Svc
Handler
Connector
ACE
FRAMEWORK
COMPONENTS
PEER
CONNECTOR
PEER
STREAM
Connection
Stream
IPC_SAP
Service
Configurator
Concurrency
global
Vanderbilt University
PEER_STREAM
SYNCH
Reactor
Douglas C. Schmidt
New subclass of
Proxy_Handler uses the
Active Object pattern for the
Consumer_Handler
Uses multi-threading and
synchronous I/O (rather than
non-blocking I/O) to transmit
message to Peers
Transparently improve
performance on a
multi-processor platform and
simplify design
260
Douglas C. Schmidt
activate() is a
pre-defined method on
ACE_Task
Vanderbilt University
261
Do
Thr_Consumer_Handler Class
Implementation
// Queue up a message for transmission.
int
Thr_Consumer_Handler::put (ACE_Message_Block *mb,
ACE_Time_Value *)
{
// Perform non-blocking enqueue.
msg_queue_->enqueue_tail (mb,
&ACE_Time_Value::zero);
}
// Transmit messages to the peer (note
// simplification resulting from threads...)
int
Thr_Consumer_Handler::svc (void)
{
ACE_Message_Block *mb = 0;
// Since this method runs in its own thread it
// is OK to block on output.
while (msg_queue_->dequeue_head (mb) != -1)
send_peer (mb);
}
Vanderbilt University
Douglas C. Schmidt
Vanderbilt University
263
Do
CCM
Stream
SUPER
VISOR
SUPER
VISOR
Session Router
Module
Event Filter
Module
MIB
Event Analyzer
Module
ACE
RUN-TIME
Switch Adapter
Module
TELECOM
SWITCHES
Vanderbilt University
EVENT
SERVER
Do
Layers
AcceptorConnector
STRATEGIC
PATTERNS
TACTICAL
PATTERNS Iterator
Component
Configurator
Reactor
Factory
Composite Method
Proxy Wrapper
Facade
Vanderbilt University
Douglas C. Schmidt
266
Do
ACE_Task
SYNCH
ACE_Module
2
SYNCH
ACE_Stream
2..*
Framework characteristics
An ACE_Stream contains a stack of
ACE_Modules
Each ACE_Module contains two ACE_Tasks
Vanderbilt University
Do
APPLICATION
Stream
Stream
Multiplexor
open()=0
close()=0
put()=0
svc()=0
STREAM
Tail
NETWORK INTERFACE
OR PSEUDO-DEVICES
MESSAGE
MODULE
WRITE
TASK
READ
TASK
Vanderbilt University
UPSTREAM
DOWNSTREAM
STREAM
Head
Do
Module
A
ACTIVE
4: svc()
Module
A
3: put()
Module
B
ACTIVE
2: svc()
1: put()
Module
C
ACTIVE
2: put()
Module
B
Module
C
TASK-BASED
PROCESS ARCHITECTURE
MESSAGE
OBJECT
MODULE
OBJECT
WRITE TASK
OBJECT
1: put()
MESSAGE-BASED
PROCESS ARCHITECTURE
READ TASK
OBJECT
PROCESS OR
THREAD
Do
Session Router
Module
SUPER
VISORS
Presentation
Module
Event Filter
Module
SUPER
VISORS
Session IO
Reactor
Event Analysis
Module
Switch IO
Presentation
Module
MD110
Switch Adapter
Module
MD110
MD110
ERICSSON
ERICSSON
ERICSSON
TELECOM
SWITCHES
www.cs.wustl.edu/schmidt/PDF/
DSEJ-94.pdf
Vanderbilt University
Douglas C. Schmidt
Features
CLIENT
CLIENT
CLIENT
SWITCHES
NETWORK
DIRECTORY
MANAGER
EXTENSION
MANAGER
CALL CENTER
MANAGER
APPLICATION
FRAMEWORK
SERVER
Vanderbilt University
271
Douglas C. Schmidt
CLIENT
CALL CENTER
MANAGER
Event
Analyzer
NETWORK
Switch
Adapter
SWITCHES
ACE
FRAMEWORK
DIRECTORY
MANAGER
DATABASE
Session
Router
Reactor
EXTENSION
MANAGER
SERVER
Vanderbilt University
272
Douglas C. Schmidt
active
4: svc()
3: put()
Producer
Module
active
1: read()
Vanderbilt University
273
Vanderbilt University
Do
Do
Vanderbilt University
Do
Do
Vanderbilt University
Do
Douglas C. Schmidt
Vanderbilt University
279
Douglas C. Schmidt
Concurrency Strategies
Developing correct, efficient, and robust concurrent applications is
challenging
Below, we examine a number of strategies that addresses
challenges related to the following:
Concurrency control
Library design
Thread creation
Deadlock and starvation avoidance
Vanderbilt University
280
Douglas C. Schmidt
281
Douglas C. Schmidt
Vanderbilt University
282
Douglas C. Schmidt
Vanderbilt University
283
Douglas C. Schmidt
Locking Alternatives
Code locking
Vanderbilt University
284
Douglas C. Schmidt
Single-lock Strategy
One way to simplify locking is use a single, application-wide mutex
lock
Each thread must acquire the lock before running and release it
upon completion
The advantage is that most legacy code doesnt require changes
The disadvantage is that parallelism is eliminated
Vanderbilt University
285
Douglas C. Schmidt
www.cs.wustl.edu/schmidt/POSA/
Monitor Object synchronization mechanisms allow concurrent
method invocations
286
Douglas C. Schmidt
i.e., the order of execution may differ from the order of invocation
This approach is more suitable to message passing-based
concurrency
The ACE_Task class can be used to implement active objects
www.cs.wustl.edu/schmidt/POSA/
Vanderbilt University
287
Douglas C. Schmidt
Invariants
In general, an invariant is a condition that is always true
For concurrent programs, an invariant is a condition that is always
true when an associated lock is not held
Vanderbilt University
288
Douglas C. Schmidt
The initial thread gets the real process stack, whose size is only
limited by the stacksize limit
All other threads get a fixed-size stack
Each thread stack is allocated off the heap and its size is fixed
at startup time
Therefore, be aware of stack smashes when debugging
multi-threaded code
Vanderbilt University
289
Douglas C. Schmidt
Deadlock
Permanent blocking by a set of threads that are competing for a set
of resources
Caused by circular waiting, e.g.,
Vanderbilt University
290
Douglas C. Schmidt
Callbacks
Inter-class method calls
There are several solutions
Vanderbilt University
291
ACE_Recursive_Thread_Mutex
Implementation
Here is portable implementation of recursive thread
mutexes available in ACE:
class ACE_Recursive_Thread_Mutex
{
public:
// Initialize a recursive mutex.
ACE_Recursive_Thread_Mutex (void);
// Implicitly release a recursive mutex.
ACE_Recursive_Thread_Mutex (void);
// Acquire a recursive mutex.
int acquire (void);
// Conditionally acquire a recursive mutex.
int tryacquire (void);
// Releases a recursive mutex.
int release (void);
private:
ACE_Thread_Mutex nesting_mutex_;
ACE_Condition_Thread_Mutex mutex_available_;
ACE_thread_t owner_;
int nesting_level_;
};
Vanderbilt University
Do
Acquiring an
ACE_Recursive_Thread_Mutex
int ACE_Recursive_Thread_Mutex::acquire (void)
{
ACE_thread_t t_id = ACE_Thread::self ();
ACE_GUARD_RETURN (ACE_Thread_Mutex, guard,
nesting_mutex_, -1);
// If theres no contention, grab mutex.
if (nesting_level_ == 0) {
owner_ = t_id;
nesting_level_ = 1;
}
else if (t_id == owner_)
// If we already own the mutex, then
// increment nesting level and proceed.
nesting_level_++;
else {
// Wait until nesting level drops
// to zero, then acquire the mutex.
while (nesting_level_ > 0)
mutex_available_.wait ();
// Note that at this point
// the nesting_mutex_ is held...
owner_ = t_id;
nesting_level_ = 1;
}
return 0;
Vanderbilt University
Do
Vanderbilt University
Do
Douglas C. Schmidt
Avoiding Starvation
Starvation occurs when a thread never acquires a mutex even
though another thread periodically releases it
The order of scheduling is often undefined
This problem may be solved via:
Vanderbilt University
295
Douglas C. Schmidt
Drawbacks to Multi-threading
Performance overhead
296
Douglas C. Schmidt
Vanderbilt University
297
Douglas C. Schmidt
Vanderbilt University
298
Douglas C. Schmidt
Vanderbilt University
299
Douglas C. Schmidt
300
Douglas C. Schmidt
301
Douglas C. Schmidt
Vanderbilt University
302
Douglas C. Schmidt
Vanderbilt University
303
www.cs.wustl.edu/schmidt/ACE.
html
Mailing lists
ace-users@cs.wustl.edu
ace-users-request@cs.wustl.edu
ace-announce@cs.wustl.edu
ace-announce-request@cs.wustl.edu
Newsgroup
comp.soft-sys.ace
Commercial support from Riverace and OCI
www.riverace.com
www.theaceorb.com
Vanderbilt University
Do
Douglas C. Schmidt
Concluding Remarks
Developers of networked application software confront recurring
challenges that are largely application-independent
Vanderbilt University
305