C++ Network Programming with Patterns, Frameworks, and ACE

tenchraceSoftware and s/w Development

Jul 14, 2012 (5 years and 1 month ago)

669 views

C++NetworkProgrammingwithPatterns,
Frameworks,andACE
DouglasC.Schmidt
ProfessorDepartmentofEECS
d.schmidt@vanderbilt.eduVanderbiltUniversity
www.cs.wustl.edu/
￿
schmidt/(615)343-8197
Sponsors
NSF,DARPA,ATD,BBN,Boeing,Cisco,Comverse,GDIS,Experian,GlobalMT,
Hughes,Kodak,Krones,Lockheed,Lucent,Microsoft,Mitre,Motorola,NASA,Nokia,
Nortel,OCI,Oresis,OTI,QNX,Raytheon,SAIC,SiemensSCR,SiemensMED,
SiemensZT,Sprint,Telcordia,USENIX
AdvancedACETutorialDouglasC.Schmidt
RoadmaptoLevelsofMiddleware
H
HO
OS
ST
T
I
IN
NF
FR
RA
AS
ST
TR
RU
UC
CT
TU
UR
RE
E
M
MI
ID
DD
DL
LE
EW
WA
AR
RE
E
D
DI
IS
ST
TR
RI
IB
BU
UT
TI
IO
ON
N
M
MI
ID
DD
DL
LE
EW
WA
AR
RE
E
CCO
OM
MM
MO
ON
N
M
MI
ID
DD
DL
LE
EW
WA
AR
RE
E
S
SE
ER
RV
VI
IC
CE
ES
S
AAP
PP
PL
LI
IC
CA
AT
TI
IO
ON
NS
S
H
HA
AR
RD
DW
WA
AR
RE
E
D
DE
EV
VI
IC
CE
ES
S
W
WT
TS
S
H
HU
UD
D
N
Na
av
v
A
AV
VI
IO
ON
NI
IC
CS
S
RRE
EP
PL
LI
IC
CA
AT
TI
IO
ON
N
SSE
ER
RV
VI
IC
CE
E
D
DO
OM
MA
AI
IN
N-
-S
SP
PE
EC
CI
IF
FI
IC
C
M
MI
ID
DD
DL
LE
EW
WA
AR
RE
E
S
SE
ER
RV
VI
IC
CE
ES
S
OOP
PE
ER
RA
AT
TI
IN
NG
G
S
SY
YS
ST
TE
EM
MS
S
&
&
P
PR
RO
OT
TO
OC
CO
OL
LS
S
E
EV
VE
EN
NT
T
CCH
HA
AN
NN
NE
EL
L
C
Co
on
ns
s
C
Co
on
ns
s
C
Co
on
ns
s
www.cs.wustl.edu/˜schmidt/PDF/
middleware-chapter.pdf
￿
Observations
–Historically,apps
builtatopOS
–Today,appsbuilt
atop
middleware
–Middlewarehas
multiplelayers
￿
Justlikenetwork
protocolstacks
VanderbiltUniversity
1
AdvancedACETutorialDouglasC.Schmidt
ChallengesandSolutions
￿
Developing
efficient
,
robust
,and
extensible
concurrentnetworking
applicationsishard

e.g.
,mustaddresscomplextopicsthatarelessproblematicornot
relevantfornon-concurrent,stand-aloneapplications
￿
OOtechniquesandOOlanguagefeatureshelptoenhancesoftware
qualityfactors
–KeyOOtechniquesinclude
patterns
and
frameworks
–KeyOOlanguagefeaturesinclude
classes
,
inheritance
,
dynamic
binding
,and
parameterizedtypes
–Keysoftwarequalityfactorsinclude
modularity
,
extensibility
,
portability
,
reusability
,and
correctness
VanderbiltUniversity
4
AdvancedACETutorialDouglasC.Schmidt
Caveats
￿
OOis
not
apanacea
–Thoughwhenusedproperlyithelpsminimize“accidental”
complexityandimprovesoftwarequalityfactors
￿
It’salsoessentialtounderstandadvancedOSfeaturestoenhance
functionalityandperformance,
e.g.
,

Multi-threading

Multi-processing

Synchronization

Sharedmemory

Explicitdynamiclinking

CommunicationprotocolsandIPCmechanisms
VanderbiltUniversity
5
AdvancedACETutorialDouglasC.Schmidt
TutorialOutline
￿
BriefoverviewofkeyOOnetworkingandconcurrencyconceptsand
OSplatformmechanisms
–Emphasisison
practical
solutions
￿
Examinearangeofexamplesindetail

NetworkedLoggingService

ConcurrentWebServer

Application-levelTelecomGateway

CallCenterManagerEventServer
￿
Discussgeneralconcurrentprogrammingstrategies
￿
ProvideURLsforfurtherreadingonthetopic
VanderbiltUniversity
6
AdvancedACETutorialDouglasC.Schmidt
SoftwareDevelopmentEnvironment
￿
ThetopicsdiscussedherearelargelyindependentofOS,network,
andprogramminglanguage
–CurrentlyusedsuccessfullyonUNIX/POSIX,Windows,and
RTOSplatforms,runningonTCP/IPnetworksusingC++
￿
ExamplesareillustratedusingfreelyavailableADAPTIVE
CommunicationEnvironment(ACE)OOframeworkcomponents
–AlthoughACEiswritteninC++,theprinciplescoveredinthis
tutorialapplytootherOOlanguages

e.g.
,Java,Eiffel,Smalltalk,etc.
￿
Inaddition,othernetworksandbackplanescanbeused,aswell
VanderbiltUniversity
7
AdvancedACETutorialDouglasC.Schmidt
SourcesofInherentComplexity
Inherentcomplexity
resultsfromfundamentaldomainchallenges,
e.g.
:
Concurrentprogramming
￿
Eliminating“raceconditions”
￿
Deadlockavoidance
￿
Fairscheduling
￿
Performanceoptimization
andtuning
Distributedprogramming
￿
Addressingtheimpactoflatency
￿
Faulttoleranceandhighavailability
￿
Loadbalancingandservice
partitioning
￿
Consistentorderingofdistributed
events
VanderbiltUniversity
9
AdvancedACETutorialDouglasC.Schmidt
SourcesofAccidentalComplexity
Accidentalcomplexity
resultsfromlimitationswithtoolsandtechniques
usedtodevelopconcurrentapplications,
e.g.
,
￿
Lackofportable,reentrant,type-safeandextensiblesystemcall
interfacesandcomponentlibraries
￿
Inadequatedebuggingsupportandlackofconcurrentand
distributedprogramanalysistools
￿
Widespreaduseof
algorithmic
decomposition
–Finefor
explaining
concurrentprogrammingconceptsand
algorithmsbutinadequatefor
developing
large-scaleconcurrent
networkapplications
￿
Continuousrediscoveryandreinventionofcoreconceptsand
components
VanderbiltUniversity
10
AdvancedACETutorialDouglasC.Schmidt
OOContributionstoConcurrent
andDistributedApplications
Concurrentnetworkprogrammingis
traditionallyperformedusing
low-levelOSmechanisms,
e.g.
,
￿
fork/exec
￿
Sharedmemoryandsemaphores
￿
Memory-mappedfiles
￿
Signals
￿
sockets/select
￿
Low-levelthreadAPIs
Patterns
and
frameworks
elevate
developmentleveltofocuson
applicationconcerns,
e.g.
,
￿
Servicefunctionalityand
policies
￿
Serviceconfiguration
￿
Concurrentevent
demultiplexingandevent
handlerdispatching
￿
Serviceconcurrencyand
synchronization
VanderbiltUniversity
11
AdvancedACETutorialDouglasC.Schmidt
OverviewofPatterns
￿
Patternsrepresent
solutions
to
problems
thatarisewhendeveloping
softwarewithinaparticular
context

i.e.
,“Patterns==problem/solutionpairswithinacontext”
￿
Patternscapturethe
static
and
dynamicstructure
and
collaboration
amongkey
participants
insoftwaredesigns
–Theyareparticularlyusefulforarticulatinghowandwhyto
resolve
non-functionalforces
￿
Patternsfacilitatereuseofsuccessfulsoftwarearchitecturesand
designs
VanderbiltUniversity
12
AdvancedACETutorialDo
Example:theProxyPattern
NETWORK
CLIENT
SERVER
2:
FORWARD REQUEST
3:
RESPONSE
:
QUOTER
1:
METHOD CALL
4:
METHOD RETURN
:
QUOTER
PROXY
:
BROKER
Intent:Provideasurrogateforanotherobjectthat
controlsaccesstoit
VanderbiltUniversity
AdvancedACETutorialDouglasC.Schmidt
OverviewofFrameworksandComponents
￿
Aframeworkis:
–“Anintegratedcollectionofcomponentsthatcollaborateto
produceareusablearchitectureforafamilyofrelatedapplications”
￿
Frameworksdifferfromconventionalclasslibraries:
1.Frameworksare“semi-complete”applications
2.Frameworksaddressaparticularapplicationdomain
3.Frameworksprovide“inversionofcontrol”
￿
Frameworksfacilitatereuseofsuccessfulnetworkedapplication
softwaredesignsandimplementations
–Applications
inherit
fromand
instantiate
frameworkcomponents
VanderbiltUniversity
14
AdvancedACETutorialDouglasC.Schmidt
ClassLibrariesversusFrameworks
NETWORKING
DATABASE
GUI
EVENT
LOOP
APPLICATION
-
SPECIFIC
FUNCTIONALITY
EVENT
LOOP
EVENT
LOOP
CALL
BACKS
INVOKES
(A
) CLASS LIBRARY ARCHITECTURE
(B)
FRAMEWORK ARCHITECTURE
DATABASE
CLASSES
NETWORK
IPC
CLASSES
MATH
CLASSES
ADT
CLASSES
GUI
CLASSES
APPLICATION
-
SPECIFIC
FUNCTIONALITY
EVENT
LOOP
GLUE
CODE
LOCAL
INVOCATIONS
ADT
CLASSES
MATH
CLASSES
Keydistinctions
￿
Classlibraries
–Reusablebuildingblocks
–Domain-independent
–Limitedinscope
–Passive
￿
Frameworks
–Reusable,“semi-complete”
applications
–Domain-specific
–Broaderinscope
–Active
VanderbiltUniversity
15
AdvancedACETutorialDouglasC.Schmidt
TheADAPTIVECommunicationEnvironment(ACE)
PROCESSES/
THREADS
DYNAMIC
LINKING
SHARED
MEMORY
SELECT/
IO COMP
FILE SYS
APIS
WIN
32 NAMED
PIPES & UNIX
STREAM PIPES
UNIX
FIFOS
C
APIS
SOCKETS
/
TLI
COMMUNICATION
SUBSYSTEM
VIRTUAL MEMORY
&
FILE
SUBSYSTEM
GENERAL OPERATING SYSTEM SERVICES
PROCESS/THREAD
SUBSYSTEM
FRAMEWORK
LAYER
ACCEPTOR
CONNECTOR
NETWORKED
SERVICE
COMPONENTS
LAYER
NAME
SERVER
TOKEN
SERVER
LOGGING
SERVER
GATEWAY
SERVER
SOCK SAP/
TLI SAP
FIFO
SAP
LOG
MSG
SERVICE
HANDLER
TIME
SERVER
C++
WRAPPER
FACADE
LAYER
SPIPE
SAP
CORBA
HANDLER
FILE
SAP
SHARED
MALLOC
THE ACE ORB
(TAO
)
JAWS ADAPTIVE
WEB SERVER
STANDARDS
-BASED MIDDLEWARE
REACTOR
/
PROACTOR
PROCESS/
THREAD
MANAGERS
STREAMS
SERVICE
CONFIG-
URATOR
SYNCH
WRAPPERS
MEM
MAP
OS ADAPTATION LAYER
www.cs.wustl.edu/˜schmidt/ACE.html
VanderbiltUniversity
16
AdvancedACETutorialDouglasC.Schmidt
ACEStatistics
￿
ACElibrarycontains
￿
250,000
linesofC++
–Over40person-yearsofeffort
￿
PortedtoUNIX,Windows,MVS,and
RT/embeddedplatforms

e.g.
,VxWorks,LynxOS,Chorus
￿
Largeuserandopen-source
developercommunity
–˜schmidt/ACE-users.html
￿
Currentlyusedby
dozensofcompanies
–Bellcore,BBN,
Boeing,Ericsson,
Hughes,Kodak,
Lockheed,Lucent,
Motorola,Nokia,
Nortel,Raytheon,
SAIC,Siemens,etc.
￿
Supportedcommercially
byRiverace
–www.riverace.com
VanderbiltUniversity
17
AdvancedACETutorialDouglasC.Schmidt
TheKeyFrameworksinACE
Acceptor-
Connector
Reactor
Proactor
Service
Configurator
Streams
Task
￿
ACEcontainsanumberofframeworksthatcanbeusedseparately
ortogether
￿
Thisdesignpermitsfine-grainedsubsettingofACEcomponents
–SubsettinghelpsminimizeACE’smemoryfootprint
–$ACE_ROOT/doc/ACE-subsets.html
VanderbiltUniversity
18
AdvancedACETutorialDouglasC.Schmidt
PatternsforCommunicationMiddleware
Event
Patterns
Concurrency
Patterns
External
Polymorphism
Wrapper
Facade
Connector
Thread
Pool
Thread-per
Session
Thread-per
Request
Asynchronous
Completion
Token
Thread
Specific
Storage
Active
Object
Half-Sync/
Half-Async
Leader/
Followers
Component
Configurator
Object
Lifetime
Manager
Reactor
Proactor
Double
Checked
Locking
Thread-
Safe
Interface
Scoped
Locking
Strategized
Locking
Initialization
Patterns
Synchronization
Patterns
Acceptor
Observation
￿
Failuresrarelyresultfrom
unknownscientific
principles,butfromfailing
toapplyproven
engineeringpracticesand
patterns
BenefitsofPatterns
￿
Facilitatedesignreuse
￿
Preservecrucialdesign
information
￿
Guidedesignchoices
VanderbiltUniversity
19
AdvancedACETutorialDouglasC.Schmidt
TheACEORB(TAO)
NETWORK
ORB RUN-TIME
SCHEDULER
operation()
IDL
STUBS
IDL
SKELETON
in args
out args + return
value
CLIENT
OS KERNEL
HIGH-SPEED
NETWORK INTERFACE
REAL
-TIME I/O
SUBSYSTEM
OBJECT
(
SERVANT
)
OS KERNEL
HIGH-SPEED
NETWORK INTERFACE
REAL
-TIME I/O
SUBSYSTEM
ACE
COMPONENTS
OBJ
REF
REAL-TIME ORB CORE
IOP
PLUGGABLE
ORB & XPORT
PROTOCOLS
IOP
PLUGGABLE
ORB & XPORT
PROTOCOLS
REAL
-TIME
OBJECT
ADAPTER
www.cs.wustl.edu/˜schmidt/TAO.
html
TAOOverview
￿
￿
Areal-time,
high-performance
ORB
￿
LeveragesACE
–RunsonPOSIX,
Windows,
RTOSs
Relatedefforts
￿
￿
QuOatBBN
￿
MIC/GMEat
Vanderbilt
￿
XOTS
VanderbiltUniversity
20
AdvancedACETutorialDouglasC.Schmidt
TAOStatistics
￿
TAOorderofmagnitude
–CoreORB
￿
300,000LOC
–IDLcompiler
￿
200,000
LOC
–CORBAObjectServices
￿
250,000LOC
–LeveragesACEheavily
￿
PortedtoUNIX,Windows,&
RT/embeddedplatforms

e.g.
,VxWorks,LynxOS,
Chorus,WinCE
￿￿
50person-yearsofeffort
￿
Currentlyusedbymany
companies

e.g.
,Boeing,BBN,Lockheed,
Lucent,Motorola,Raytheon,
SAIC,Siemens,etc.
￿
SupportedcommerciallybyOCI
andPrismTech
–www.ociweb.com
–www.prismtechnologies.com
VanderbiltUniversity
21
AdvancedACETutorialDouglasC.Schmidt
JAWSAdaptiveWebServer
WWWWWW
SERVERSERVER
2: index.html2: index.html
1: GET ~schmidt1: GET ~schmidt
HTTP/1.0HTTP/1.0
COMMUNICATION PROTOCOLCOMMUNICATION PROTOCOL
((EE..GG.,., HTTP HTTP))
GUIGUI
HTMLHTML
PARSERPARSER
REQUESTERREQUESTER
GRAPHICSGRAPHICS
ADAPTERADAPTER
NETWORK
OS KERNEL
OS I/O SUBSYSTEM
NETWORK ADAPTERS
OS KERNEL
OS I/O SUBSYSTEM
NETWORK ADAPTERS
DISPATCHER
PROTOCOL
HANDLERS
WWW
CLIENTCLIENT
www.cs.wustl.edu/˜jxh/
research/
￿
JAWSOverview
–Ahigh-performance
Webserver
￿
Flexibleconcurrency
anddispatching
mechanisms
–LeveragestheACE
framework
￿
PortedtomostOS
platforms
–Usedcommerciallyby
CacheFlow
￿
www.cacheflow.com
VanderbiltUniversity
22
AdvancedACETutorialDouglasC.Schmidt
JavaACE
FRAMEWORKS
AND CLASS
CATEGORIES
DISTRIBUTED
SERVICES AND
COMPONENTS
NAME
SERVER
TOKEN
SERVER
LOGGING
SERVER
TIME
SERVER
JAVA
WRAPPERS
SYNCH
WRAPPERS
SOCK_SAP
THREAD
MANAGER
LOG
MSG
TIMER
QUEUE
SERVICE
CONFIGURATOR
ADAPTIVE SERVICE EXECUTIVE
(ASX)
ACCEPTOR
CONNECTOR
SERVICE
HANDLER
JAVA VIRTUAL MACHINE
(JVM)
www.cs.wustl.edu/˜schmidt/JACE.html
www.cs.wustl.edu/˜schmidt/C++2java.
html
www.cs.wustl.edu/˜schmidt/PDF/
MedJava.pdf
JavaACE
Overview
￿
AJavaversion
ofACE
–Usedfor
medical
imaging
prototype
VanderbiltUniversity
23
AdvancedACETutorialDo
NetworkedLoggingService
P
1
P
2
P
3
LOCAL
IPC
CLIENT
LOGGING
DAEMON
P
1
P
2
P
3
LOCAL
IPC
CLIENT
LOGGING
DAEMON
NETWORK
STORAGE
DEVICE
H
OST
A
H
OST
B
A
B
SERVER LOGGING
DAEMON
SERVER
CLIENT
HOST
A
REMOTE
IPC
HOST
B
REMOTE
IPC
CLIENT
CONSOLE
PRINTER
Intent:Serverloggingdaemoncollects,formats,
andoutputsloggingrecordsforwardedfromclient
loggingdaemonsresidingthroughoutanetworkor
Internet
VanderbiltUniversity
AdvancedACETutorialDouglasC.Schmidt
NetworkedLoggingServiceProgrammingAPI
TheloggingAPIissimilartoprintf(),
e.g.
:
ACE_ERROR((LM_ERROR,"(%t)forkfailed"));Generatesonloggingserverhost:Oct3114:50:131992@tango.ics.uci.edu@2766@LM_ERROR@client
::(4)forkfailed and
ACE_DEBUG((LM_DEBUG,
"(%t)sendingtoserver%s",server_host));
generatesonloggingserverhost:Oct3114:50:281992@zola.ics.uci.edu@18352@LM_DEBUG@drwho
::(6)sendingtoserverbastille
VanderbiltUniversity
25
AdvancedACETutorialDouglasC.Schmidt
ConventionalLoggingServerDesign
Typicalalgorithmicpseudo-codefor
networkedloggingserver:
voidlogging_server(void){
initializeacceptorendpoint
loopforever{
waitforevents
handledataevents
handleconnectionevents
}
}
The“grandmistake:”
￿
Avoidthetemptationto
“step-wiserefine”this
algorithmically
decomposed
pseudo-codedirectlyinto
thedetaileddesignand
implementationofthe
loggingserver!
VanderbiltUniversity
26
AdvancedACETutorialDo
Theselect()-basedLoggingServer
Implementation
NETWORK
SERVER
LOGGING DAEMON
maxhandlep1
read_handles
CONNECTION
REQUEST
LOGGING
RECORDS
LOGGING
RECORDS
LOGGING
RECORDS
CLIENT
CLIENT
CLIENT
CLIENT
SERVER
acceptor
Serializesserverprocessingatselect()
demuxinglevel
VanderbiltUniversity
AdvancedACETutorialDo
ConventionalLoggingServer
Implementation
Notetheexcessiveamountofdetailrequiredto
programatthesocketlevel...
//Mainprogram
staticconstintPORT=10000;
typedefu_longCOUNTER;
typedefintHANDLE;
//Countsthe#ofloggingrecordsprocessed
staticCOUNTERrequest_count;
//Acceptor-modesockethandle
staticHANDLEacceptor;
//Highestactivehandlenumber,plus1
staticHANDLEmaxhp1;
//Setofcurrentlyactivehandles
staticfd_setactivity_handles;
//Scratchcopyofactivity_handles
staticfd_setready_handles;
VanderbiltUniversity
AdvancedACETutorialDo
MainEventLoopofLoggingServer
intmain(intargc,char*argv[])
{
initialize_acceptor
(argc>1?atoi(argv[1]):PORT);
//Loopforeverperforminglogging
//serverprocessing.
for(;;){
//structassignment.
ready_handles=activity_handles;
//WaitforclientI/Oevents.
select(maxhp1,&ready_handles,0,0,0);
//Firstreceivependingloggingrecords.
handle_data();
//Thenacceptpendingconnections.
handle_connections();
}
}
VanderbiltUniversity
AdvancedACETutorialDo
InitializeAcceptorSocket
staticvoidinitialize_acceptor(u_shortport)
{
structsockaddr_insaddr;
//Createalocalendpointofcommunication.
acceptor=socket(PF_INET,SOCK_STREAM,0);
//Setuptheaddressinfo.tobecomeserver.
memset((void*)&saddr,0,sizeofsaddr);
saddr.sin_family=AF_INET;
saddr.sin_port=htons(port);
saddr.sin_addr.s_addr=htonl(INADDR_ANY);
//Associateaddresswithendpoint
bind(acceptor,
(structsockaddr*)&saddr,
sizeofsaddr);
//Makeendpointlistenforconnectionrequests.
listen(acceptor,5);
//Initializehandlesets.
FD_ZERO(&ready_handles);
FD_ZERO(&activity_handles);
FD_SET(acceptor,&activity_handles);
maxhp1=acceptor+1;
}
VanderbiltUniversity
AdvancedACETutorialDo
HandleDataProcessing
staticvoidhandle_data(void){
//acceptor+1isthelowestclienthandle
for(HANDLEh=acceptor+1;h<maxhp1;h++)
if(FD_ISSET(h,&ready_handles)){
ssize_tn=handle_log_record(h,1);
//Guaranteednottoblockinthiscase!
if(n>0)
++request_count;
//Countthe#ofloggingrecords
elseif(n==0){
//Handleconnectionshutdown.
FD_CLR(h,&activity_handles);
close(h);
if(h+1==maxhp1){
//Skippastunusedhandles
while(!FD_ISSET(--h,
&activity_handles))
continue;
maxhp1=h+1;
}
}
}
}
VanderbiltUniversity
AdvancedACETutorialDo
ReceiveandProcessLoggingRecords
staticssize_thandle_log_record(HANDLEin_h,
HANDLEout_h){
ssize_tn;
size_tlen;
Log_Recordlr;
//Thefirstrecvreadsthelength(storedasa
//fixed-sizeinteger)ofadjacentloggingrecord.
n=recv(in_h,(char*)&len,sizeoflen,0);
if(n<=0)returnn;
len=ntohl(len);//Convertbyte-ordering
//Thesecondrecvthenreads<len>bytesto
//obtaintheactualrecord.
for(size_tnread=0;nread<len;nread+=n
n=recv(in_h,((char*)&lr)+nread,
len-nread,0);
//Decodeandprintrecord.
decode_log_record(&lr);
if(write(out_h,lr.buf,lr.size)==-1)
return-1;
elsereturn0;
}
VanderbiltUniversity
AdvancedACETutorialDo
HandleConnectionAcceptance
staticvoidhandle_connections(void)
{
if(FD_ISSET(acceptor,&ready_handles)){
staticstructtimevalpoll_tv={0,0};
HANDLEh;
//Handleallpendingconnectionrequests
//(noteuseofselect’spollingfeature)
do{
//Bewareofsubtlebug(s)here...
h=accept(acceptor,0,0);
FD_SET(h,&activity_handles);
//Growmax.sockethandleifnecessary.
if(h>=maxhp1)
maxhp1=h+1;
}while(select(acceptor+1,&ready_handles,
0,0,&poll_tv)==1);
}
VanderbiltUniversity
AdvancedACETutorialDo
ConventionalClientLogging
DaemonImplementation
Themain()methodreceivesloggingrecordsfrom
clientapplicationsandforwardsthemontothe
loggingserver
intmain(intargc,char*argv[])
{
HANDLEstream=initialize_stream_endpoint
(argc>1
?atoi(argv[1])
:PORT);
Log_Recordlr;
//Loopforeverperformingclient
//loggingdaemonprocessing.
for(;;){
//...getloggingrecordsfromclient
//applicationprocesses...
size_tsize=htonl(lr.size);
send(stream,&size,sizeofsize);
encode_log_record(&lr);
send(stream,((char*)&lr),sizeoflr);
}
}
VanderbiltUniversity
AdvancedACETutorialDo
ClientConnectionEstablishment
staticHANDLEinitialize_stream_endpoint
(constchar*host,u_shortport)
{
structsockaddr_insaddr;
//Createalocalendpointofcommunication.
HANDLEstream=socket(PF_INET,SOCK_STREAM,0);
//Setuptheaddressinfo.tobecomeclient.
memset((void*)&saddr,0,sizeofsaddr);
saddr.sin_family=AF_INET;
saddr.sin_port=htons(port);
hostent*hp=gethostbyname(host);
memcpy((void*)&saddr,
htonl(hp->h_addr),
hp->h_length);
//Associateaddresswithendpoint
connect(stream,
(structsockaddr*)&saddr,
sizeofsaddr);
returnstream;
}
VanderbiltUniversity
AdvancedACETutorialDouglasC.Schmidt
LimitationswithAlgorithmicDecomposition
Algorithmicdecompositiontightlycouplesapplication-specific
functionality
andthefollowingconfiguration-relatedcharacteristics:
￿
ApplicationStructure
–Thenumberofservicesperprocess
–Timewhenservicesareconfiguredintoaprocess
￿
CommunicationandDemultiplexingMechanisms
–TheunderlyingIPCmechanismsthatcommunicatewithother
participatingclientsandservers
–Eventdemultiplexingandeventhandlerdispatchingmechanisms
￿
ConcurrencyandSynchronizationModel
–Theprocessand/orthreadarchitecturethatexecutesservice(s)at
run-time
VanderbiltUniversity
36
AdvancedACETutorialDouglasC.Schmidt
OvercomingLimitationsviaOO
￿
Thealgorithmicdecompositionillustratedabovespecifies
many
low-leveldetails
–Moreover,theexcessivecouplingimpedesreusability,
extensibility,andportability...
￿
Incontrast,OOfocuseson
application-specific
behavior,
e.g.
,
intLogging_Handler::handle_input(void)
{
ssize_tn=handle_log_record(peer().get_handle(),
ACE_STDOUT);
if(n>0)
++request_count;//Countthe#ofloggingrecords
returnn<=0?-1:0;
}
VanderbiltUniversity
37
AdvancedACETutorialDouglasC.Schmidt
OOContributionstoSoftware
￿
Patterns
facilitatethelarge-scalereuseofsoftwarearchitecture
–Evenwhenreuseofalgorithms,detaileddesigns,and
implementationsisnotfeasible
￿
Frameworks
achievelarge-scaledesignandcodereuse
–Incontrast,traditionaltechniquesfocusonthe
functions
and
algorithms
thatsolveparticularrequirements
￿
NotethatpatternsandframeworksarenotuniquetoOO!
–However,objectsandclassesareusefulabstractionmechanisms
VanderbiltUniversity
38
AdvancedACETutorialDouglasC.Schmidt
PatternsintheNetworkedLoggingServer
Iterator
Adapter
Template
Method
Factory
Method
Wrapper
Facade
TACTICAL PATTERNS
STRATEGIC
PATTERNS
Acceptor
Active
Object
Component
Configurator
Reactor
￿
Strategic
and
tactical
arerelativetothe
context
and
abstractionlevel
VanderbiltUniversity
39
AdvancedACETutorialDouglasC.Schmidt
SummaryofPatternIntents
￿
WrapperFacade
￿
“Encapsulatesthefunctionsanddataprovided
byexistingnon-OOAPIswithinmoreconcise,robust,portable,
maintainable,andcohesiveOOclassinterfaces”
￿
Reactor
￿
“Demultiplexesanddispatchesrequeststhatare
deliveredconcurrentlytoanapplicationbyoneormoreclients”
￿
Acceptor
￿
“Decouplethepassiveconnectionandinitializationofa
peerserviceinadistributedsystemfromtheprocessingperformed
oncethepeerserviceisconnectedandinitialized”
￿
ComponentConfigurator
￿
“Decouplestheimplementationof
servicesfromthetimewhentheyareconfigured”
￿
ActiveObject
￿
“Decouplesmethodexecutionfrommethod
invocationtoenhanceconcurrencyandsimplifysynchronized
accesstoanobjectthatresidesinitsownthreadofcontrol”
VanderbiltUniversity
40
AdvancedACETutorialDouglasC.Schmidt
ComponentsintheOOLoggingServer
￿
Application-specificcomponents
–Processloggingrecordsreceivedfromclients
￿
Connection-orientedapplicationcomponents
–ACE_Svc_Handler(servicehandler)
￿
PerformsI/O-relatedtaskswithclients
–ACE_Acceptorfactory
￿
Passivelyacceptsconnectionrequests
￿
Dynamicallycreatesaservicehandlerforeachclientand
“activates”it
￿
Application-independentACEframeworkcomponents
–PerformIPC,explicitdynamiclinking,eventdemultiplexing,event
handlerdispatching,multi-threading,etc.
VanderbiltUniversity
41
AdvancedACETutorialDo
ClassDiagramforOOLoggingServer
Service
Configurator
Stream
Connection
Logging
Acceptor
Logging_Handler
SOCK_Acceptor
Logging
Handler
SOCK_Stream
Null_Synch
SVC_HANDLER
PEER_ACCEPTOR
PEER_STREAM
SYNCH_STRAT
CONNECTION-
ORIENTED
COMPONENTS
APPLICATION
-
SPECIFIC
COMPONENTS
ACE
FRAMEWORK
COMPONENTS
IPC_SAP
Reactor
<<activates>>
1
n
Concurrency
PEER
ACCEPTOR
PEER
STREAM
Svc
Handler
Acceptor
VanderbiltUniversity
AdvancedACETutorialDouglasC.Schmidt
AddressingRobustness,Portability,
andMaintainabilityChallenges
￿
Problem
–Buildingdistributedapplicationsusinglow-levelAPIsishard
￿
Forces
–Low-levelAPIsareverbose,tedious,anderror-pronetoprogram
–Low-levelAPIsarenon-portableandnon-maintainable
￿
Solution
–Applythe
WrapperFacade
patterntoencapsulatelow-level
functionsanddatastructures
VanderbiltUniversity
43
AdvancedACETutorialDouglasC.Schmidt
TheWrapperFacadePattern
Intent
￿
Encapsulatesthefunctions
anddataprovidedby
existinglower-level,
non-OOAPIswithinmore
concise,robust,portable,
maintainable,andcohesive
higher-levelOOclass
interfaces
1: method_k()
2: function_k()
client
Functions
function_1()
...
function_n()
Wrapper
Facade
method_1()
...
method_m()
POSA2(www.cs.wustl.edu/
˜schmidt/POSA/)
ForcesResolved
￿
Avoidtedious,error-prone,andnon-portablesystemAPIs
￿
Createcohesiveabstractions
VanderbiltUniversity
44
AdvancedACETutorialDo
MotivatingtheWrapperFacadePattern:
theSocketAPI
SERVER
CLIENT
socket()
bind()
(optional)
connect()
send()/recv()
socket()
bind()
listen()
accept()
send()/recv()
2:
ACTIVE
ROLE
3:
SERVICE
PROCESSING
close()
close()
NETWORK
1:
PASSIVE
ROLE
Socketsarethemostcommonnetwork
programmingAPIandareavailableonmostOS
platforms
VanderbiltUniversity
AdvancedACETutorialDouglasC.Schmidt
ProblemwithSockets:LackofType-safety
intbuggy_echo_server(u_shortport_num)
{//Errorcheckingomitted.
sockaddr_ins_addr;
intacceptor=
socket(PF_UNIX,SOCK_DGRAM,0);
s_addr.sin_family=AF_INET;
s_addr.sin_port=port_num;
s_addr.sin_addr.s_addr=INADDR_ANY;
bind(acceptor,(sockaddr*)&s_addr,
sizeofs_addr);
inthandle=accept(acceptor,0,0);
for(;;){
charbuf[BUFSIZ];
ssize_tn=read(acceptor,buf,sizeofbuf);
if(n<=0)break;
write(handle,buf,n);
}
}
￿
I/Ohandlesare
notamenableto
strongtype
checkingat
compile-time
￿
Theadjacent
codecontains
manysubtle,
commonbugs
VanderbiltUniversity
46
AdvancedACETutorialDouglasC.Schmidt
ProblemwithSockets:SteepLearningCurve
Manysocket/TLIAPIfunctionshavecomplexsemantics,
e.g.
:
￿
Multipleprotocolfamiliesandaddressfamilies

e.g.
,TCP,UNIXdomain,OSI,XNS,etc.
￿
Infrequentlyusedfeatures,
e.g.
:
–Broadcasting/multicasting
–Passingopenfilehandles
–Urgentdatadeliveryandreception
–AsynchI/O,non-blockingI/O,I/O-basedandtimer-basedevent
multiplexing
VanderbiltUniversity
47
AdvancedACETutorialDouglasC.Schmidt
ProblemwithSockets:Portability
￿
Havingmultiple“standards,”
i.e.
,socketsandTLI,makesportability
difficult,
e.g.
,
–Mayrequireconditionalcompilation
–Inaddition,relatedfunctionsarenotincludedinPOSIXstandards
￿
e.g.
,select(),WaitForMultipleObjects(),andpoll()
￿
PortabilitybetweenUNIXandWindowsSocketsisproblematic,
e.g.
:
–Headerfiles
–Errornumbers
–Handlevs.descriptortypes
–Shutdownsemantics
–I/Ocontrolsandsocketoptions
VanderbiltUniversity
48
AdvancedACETutorialDouglasC.Schmidt
ProblemwithSockets:PoorlyStructured
socket()
bind()
connect()
listen()
accept()
read()
write()
readv()
writev()
recv()
send()
recvfrom()
sendto()
recvmsg()
sendmsg()
setsockopt()
getsockopt()
getpeername()
getsockname()
gethostbyname()
getservbyname()
Limitations
￿
SocketAPIis
linear
ratherthan
hierarchical
￿
Thereisnoconsistencyamongnames...
￿
Non-portable
VanderbiltUniversity
49
AdvancedACETutorialDo
SocketTaxonomy
XFER
CONNECTION
/
COMMUNICATION
ROLE
LOCAL
LOCAL
/
REMOTE
STREAM
ACTIVE
PASSIVE
DATA
GRAM
CONNECTED
DATAGRAM
TYPE OF COMMUNICATION SERVICE
COMMUNICATION DOMAIN
sendto()/recvfrom()
socket(PF_UNIX)/bind()
socket(PF_INET)/bind()
send()/recv()
socket(PF_UNIX)
bind()/connect()
socket(PF_UNIX)
bind()/listen()/accept()
socket(PF_UNIX)
bind()/connect()
send()/recv()
socket(PF_INET)
bind()/listen()/accept()
socket(PF_INET)
bind()/connect()
send()/recv()
socket(PF_UNIX)/bind()
send()/recv()
sendto()/recvfrom()
socket(PF_INET)/bind()
socket(PF_INET)
bind()/connect()
socket(PF_UNIX)
bind()/connect()
socket(PF_INET)
bind()/connect()
TheSocketAPIcanbeclassifiedalongthree
dimensions
1.Connectionrole
2.Communicationdomain
3.Typeofservice
VanderbiltUniversity
AdvancedACETutorialDo
Solution:ACESocketWrapperFacades
XFER
LOCAL
LOCAL
/
REMOTE
STREAM
ACTIVE
PASSIVE
DATA
GRAM
CONNECTED
DATAGRAM
COMMUNICATION DOMAIN
LSOCK_Connector
SOCK_Connector
SOCK_Acceptor
LSOCK_Acceptor
SOCK_Dgram_Mcast
LSOCK_Stream
SOCK_Stream
LSOCK_CODgram
SOCK_CODgram
SOCK_Dgram
LSOCK_Dgram
SOCK_Dgram
SOCK_Dgram_Bcast
TYPE OF COMMUNICATION SERVICE
CONNECTION
/
COMMUNICATION
ROLE
LSOCK_Dgram
TheACEC++wrapperfacadesmoreexplicitly
modelthekeysocketcomponentsusingOO
classes
VanderbiltUniversity
AdvancedACETutorialDo
TheACEConnection-Oriented
SocketWrapperFacades
ACE_IPC_SAP
ACE_Addr
ACE_SOCK_IO
ACE_SOCK
ACE_SOCK_Acceptor
ACE_INET_Addr
ACE_SOCK_Stream
ACE_SOCK_Connector
Participants
￿
Passiveandactiveconnectionfactories
–ACE_SOCK_AcceptorandACE_SOCK_Connector
￿
Streamingclasses
–ACE_SOCK_StreamandACE_SOCK_IO
￿
Addressingclasses
–ACE_AddrandACE_INET_Addr
VanderbiltUniversity
AdvancedACETutorialDouglasC.Schmidt
TheACEConnection-OrientedSocket
WrapperFacadeFactories
classACE_SOCK_Connector
{
public:
//Traits
typedefACE_INET_AddrPEER_ADDR;
typedefACE_SOCK_StreamPEER_STREAM;
intconnect
(ACE_SOCK_Stream&new_sap,
constACE_INET_Addr&raddr,
ACE_Time_Value*timeout,
constACE_INET_Addr&laddr);
//...
};
classACE_SOCK_Acceptor
:publicACE_SOCK
{
public:
//Traits
typedefACE_INET_AddrPEER_ADDR;
typedefACE_SOCK_StreamPEER_STREAM;
ACE_SOCK_Acceptor(constACE_INET_Addr&);
intopen(constACE_INET_Addr&addr);
intaccept
(ACE_SOCK_Stream&new_sap,
ACE_INET_Addr*,
ACE_Time_Value*);
//...
};
VanderbiltUniversity
53
AdvancedACETutorialDouglasC.Schmidt
ACEConnection-OrientedSocketWrapperFacade
StreamingandAddressingClasses
classACE_SOCK_Stream
:publicACE_SOCK{
public:
//Trait.
typedefACE_INET_AddrPEER_ADDR;
ssize_tsend(constvoid*buf,
intn);
ssize_trecv(void*buf,
intn);
ssize_tsend_n(constvoid*buf,
intn);
ssize_tsendv_n(constiovec*iov,
intn);
ssize_trecv_n(void*buf,intn);
intclose(void);
//...
};
classACE_INET_Addr
:publicACE_Addr
{
public:
ACE_INET_Addr(u_shortport,
constcharhost[]);
u_shortget_port_number(void);
ACE_UINT_32get_ip_addr(void);
//...
};
VanderbiltUniversity
54
AdvancedACETutorialDouglasC.Schmidt
DesignInterlude:Motivatingthe
SocketWrapperFacadeStructure
￿
Q:
WhydecoupletheACE_SOCK_Acceptorandthe
ACE_SOCK_ConnectorfromACE_SOCK_Stream?
￿
A:ForthesamereasonsthatACE_Acceptorand
ACE_ConnectoraredecoupledfromACE_Svc_Handler,
e.g.
,
–AnACE_SOCK_Streamisonlyresponsiblefordatatransfer
￿
Regardlessofwhethertheconnectionisestablishedpassively
oractively
–ThisensuresthattheACE_SOCK*componentsaren’tused
incorrectly...
￿
e.g.
,youcan’taccidentallyread()orwrite()on
ACE_SOCK_ConnectorsorACE_SOCK_Acceptors,etc.
VanderbiltUniversity
55
AdvancedACETutorialDo
AnEchoServerWrittenusing
ACEC++SocketWrapperFacades
intecho_server(u_shortport_num)
{
//Localserveraddress.
ACE_INET_Addrmy_addr(port_num);
//Initializetheacceptormodeserver.
ACE_SOCK_Acceptoracceptor(my_addr);
//Datatransferobject.
ACE_SOCK_Streamnew_stream;
//Acceptanewconnection.
acceptor.accept(new_stream);
for(;;){
charbuf[BUFSIZ];
//Errorcaughtatcompiletime!
ssize_tn=
acceptor.recv(buf,sizeofbuf);
new_stream.send_n(buf,n);
}
}
VanderbiltUniversity
AdvancedACETutorialDo
AGenericVersionoftheEchoServer
template<classACCEPTOR>
intecho_server(u_shortport)
{
//Localserveraddress(notetraits).
typename
ACCEPTOR::PEER_ADDRmy_addr(port);
//Initializetheacceptormodeserver.
ACCEPTORacceptor(my_addr);
//Datatransferobject(notetraits).
typenameACCEPTOR::PEER_STREAMstream;
//Acceptanewconnection.
acceptor.accept(stream);
for(;;){
charbuf[BUFSIZ];
ssize_tn=
stream.recv(buf,sizeofbuf);
stream.send_n(buf,n);
}
}
VanderbiltUniversity
AdvancedACETutorialDouglasC.Schmidt
ScopeoftheACEIPCWrapperFacades
A
AC
CE
E
IIP
PC
C
SSA
AP
P
A
A
SOCKET
API
SSO
OC
CK
K
SSA
AP
P
TLI
API
TTL
LI
I
SSA
AP
P
STREAM
PIPE API
SSP
PI
IP
PE
E
SSA
AP
P
NAMED
PIPE API
FFI
IF
FO
O
SSA
AP
P
S
SS
SL
L
SSA
AP
P
SSL
API
MMAP
API
MME
EM
M
SSA
AP
P
SYSTEM V
IPC API
SSy
ys
sV
V
IIP
PC
C
C++NPv1(www.cs.wustl.edu/˜schmidt/ACE/book1/)
VanderbiltUniversity
58
AdvancedACETutorialDo
UsingtheWrapperFacadePattern
fortheLoggingServer
Notewehaven’timprovedtheoveralldesign(yet)
//...Sameasbefore...
//Acceptor-modesockethandle.
staticACE_SOCK_Acceptoracceptor;
//Setofcurrentlyactivehandles
staticACE_Handle_Setactivity_handles;
//Scratchcopyofactivity_handles
staticACE_Handle_Setready_handles;
staticvoidinitialize_acceptor(u_shortport)
{
//Setupaddressinfo.tobecomeserver.
ACE_INET_Addrsaddr(port);
//Createalocalendpointofcommunication.
acceptor.open(saddr);
//Setthe<SOCK_Acceptor>intonon-blockingmode.
acceptor.enable(ACE_NONBLOCK);
activity_handles.set_bit(acceptor.get_handle());
}
VanderbiltUniversity
AdvancedACETutorialDo
MainEventLoopofLoggingServer
intmain(intargc,char*argv[])
{
initialize_acceptor
(argc>1?atoi(argv[1]):PORT);
//Loopforeverperforminglogging
//serverprocessing.
for(;;){
//objectassignment.
ready_handles=activity_handles;
//WaitforclientI/Oevents.
ACE::select(int(maxhp1),
//callsoperatorfd_set*().
ready_handles);
//Firstreceivependingloggingrecords.
handle_data();
//Thenacceptpendingconnections.
handle_connections();
}
}
VanderbiltUniversity
AdvancedACETutorialDo
HandlingConnectionsand
DataProcessing
staticvoidhandle_connections(void){
if(ready_handles.is_set(acceptor.get_handle()))
ACE_SOCK_Streamstr;
//Handleallpendingconnectionrequests.
while(acceptor.accept(str)!=-1)
activity_handles.set_bit(str.get_handle());
}
}
staticvoidhandle_data(void){
ACE_HANDLEh;
ACE_Handle_Set_Iteratoriter(ready_handles);
while((h=iter())!=ACE_INVALID_HANDLE){
ACE_SOCK_Streamstr(h);
ssize_tn=handle_log_record(str,ACE_STDOUT);
if(n>0)//Count#ofloggingrecords.
++request_count;
elseif(n==0){
//Handleconnectionshutdown.
activity_handles.clr_bit(h);
s.close();
}
}
VanderbiltUniversity
AdvancedACETutorialDo
ReceiveandProcessLoggingRecords
staticssize_thandle_log_record(ACE_SOCK_Streams,
ACE_HANDLEout_h)
ACE_UINT_32len;
ACE_Log_Recordlr;
//Thefirstrecvreadsthelength(storedasa
//fixed-sizeinteger)ofadjacentloggingrecord.
ssize_tn=s.recv_n((char*)&len,sizeoflen);
if(n<=0)returnn;
len=ntohl(len);//Convertbyte-ordering
//Performsanitycheck!
if(len>sizeof(lr))return-1;
//Thesecondrecvthenreads<len>bytesto
//obtaintheactualrecord.
s.recv_n((char*)&lr,sizeoflr);
//Decodeandprintrecord.
decode_log_record(&lr);
if(ACE_OS::write(out_h,lr.buf,lr.size)==-1)
return-1;
elsereturn0;
}
VanderbiltUniversity
AdvancedACETutorialDo
OOClientLogging
DaemonImplementation
intmain(intargc,char*argv[])
{
ACE_SOCK_Streamstream;
ACE_SOCK_Connectorcon;//Establishconnection.
con.connect(stream,ACE_INET_Addr(argc>1
?atoi(argv[1]):PORT));
ACE_Log_Recordlr;
//Loopforeverperformingclient
//loggingdaemonprocessing.
for(;;){
//...getloggingrecordsfromclient
//applicationprocesses...
ACE_UINT_32size=lr.size;
lr.size=htonl(lr.size);
encode_log_record(&lr);
ioveciov[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;
//Useswritev(2);
stream.sendv_n(iov,2);
}
}
VanderbiltUniversity
AdvancedACETutorialDouglasC.Schmidt
EvaluatingtheWrapperFacadeSolution
Benefits
￿
Moreconcise
￿
Morerobust
￿
Moreportable
￿
Moremaintainable
￿
Moreefficient
Liabilities
￿
Potentiallymoreindirection
￿
Additionallearningcurve
￿
Stillhaven’tsolvedtheoverall
designproblem

i.e.
,theoveralldesignis
stillbasedonstep-wise
refinementoffunctions
VanderbiltUniversity
64
AdvancedACETutorialDouglasC.Schmidt
ACEC++WrapperFacade
DesignRefactoringPrinciples
￿
Enforcetypesafetyatcompile-time
￿
Allowcontrolledviolationsoftypesafety
￿
Simplifyforthecommoncase
￿
Replaceone-dimensionalinterfaceswithhierarchicalclass
categories
￿
Enhanceportabilitywithparameterizedtypes
￿
Inlineperformancecriticalmethods
￿
Defineauxiliaryclassestohideerror-pronedetails
VanderbiltUniversity
65
AdvancedACETutorialDouglasC.Schmidt
EnforceTypesafetyatCompile-Time
Socketscannotdetectcertainerrorsatcompile-time,
e.g.
,
intacceptor=socket(PF_INET,SOCK_STREAM,0);
//...
bind(acceptor,...);//Bindaddress.
listen(acceptor);//Makeaacceptor-modesocket.
HANDLEn_sd=accept(acceptor,0,0);
//Errornotdetecteduntilrun-time.
read(acceptor,buf,sizeofbuf);ACEenforcestype-safetyatcompile-timevia
factories
,
e.g.
:
ACE_SOCK_Acceptoracceptor(port);
//Error:recv()notamethodof<ACE_SOCK_Acceptor>.
acceptor.recv(buf,sizeofbuf);
VanderbiltUniversity
66
AdvancedACETutorialDouglasC.Schmidt
AllowControlledViolationsofTypesafety
MakeiteasytousetheC++Socketwrapperfacadescorrectly,hardto
useitincorrectly,butnotimpossibletouseitinwaystheclass
designersdidnotanticipate
￿
e.g.
,itmaybenecessarytoretrievetheunderlyingsockethandle:
ACE_SOCK_Acceptoracceptor;
//...
ACE_Handle_Setready_handles;
//...
if(ready_handles.is_set(acceptor.get_handle())
ACE::select(acceptor.get_handle()+1,ready_handles);
VanderbiltUniversity
67
AdvancedACETutorialDouglasC.Schmidt
SupplyDefaultParameters
ACE_SOCK_Connector(ACE_SOCK_Stream&new_stream,
constACE_Addr&remote_sap,
ACE_Time_Value*timeout=0,
constACE_Addr&local_sap=ACE_Addr::sap_any,
intprotocol_family=PF_INET,
intprotocol=0);
Theresultisextremelyconciseforthecommoncase:ACE_SOCK_Streamstream;
//Compilersuppliesdefaultvalues.
ACE_SOCK_Connectorcon(stream,ACE_INET_Addr(port,host));
VanderbiltUniversity
68
AdvancedACETutorialDo
DefineParsimoniousInterfaces
e.g.,useLSOCKtopasssockethandles:
ACE_LSOCK_Streamstream;
ACE_LSOCK_Acceptoracceptor("/tmp/foo");
acceptor.accept(stream);
stream.send_handle(stream.get_handle());
versusthelessparsimoniousBSD4.3socketcode
ACE_LSOCK::send_handle
(constACE_HANDLEsd)const{
u_chara[2];ioveciov;msghdrsend_msg;
a[0]=0xab,a[1]=0xcd;
iov.iov_base=(char*)a;
iov.iov_len=sizeofa;
send_msg.msg_iov=&iov;
send_msg.msg_iovlen=1;
send_msg.msg_name=(char*)0;
send_msg.msg_namelen=0;
send_msg.msg_accrights=(char*)&sd;
send_msg.msg_accrightslen=sizeofsd;
returnsendmsg(this->get_handle(),
&send_msg,0);
NotethatSVR4andBSD4.4APIsaredifferent
thanBSD4.3!
VanderbiltUniversity
AdvancedACETutorialDouglasC.Schmidt
CombineMultipleOperationsintoOneOperation
Creatingaconventionalacceptor-modesocketrequiresmultiplecalls:intacceptor=socket(PF_INET,SOCK_STREAM,0);
sockaddr_inaddr;
memset(&addr,0,sizeofaddr);
addr.sin_family=AF_INET;
addr.sin_port=htons(port);
addr.sin_addr.s_addr=INADDR_ANY;
bind(acceptor,&addr,addr_len);
listen(acceptor);
//...ACE_SOCK_Acceptorcombinesthisintoasingleoperation:
ACE_SOCK_Acceptoracceptor((ACE_INET_Addr)port);
VanderbiltUniversity
70
AdvancedACETutorialDouglasC.Schmidt
CreateHierarchicalClassCategories
A
AC
CE
E
LLS
SO
OC
CK
K
AAC
CE
E
IIP
PC
C
SSA
AP
P
G
GR
RO
OU
UP
P
CCO
OM
MM
M
DDA
AT
TA
AG
GR
RA
AM
M
CCO
OM
MM
M
SST
TR
RE
EA
AM
M
CCO
OM
MM
M
CCO
ON
NN
NE
EC
CT
TI
IO
ON
N
EES
ST
TA
AB
BL
LI
IS
SH
HM
ME
EN
NT
T
A
AC
CE
E
SSO
OC
CK
K
A
AC
CE
E
SSO
OC
CK
K
CCO
OD
Dg
gr
ra
am
m

A
AC
CE
E
SSO
OC
CK
K
DDg
gr
ra
am
m
ACE
SOCK
Dgram
Bcast
AAC
CE
E
SSO
OC
CK
K
AAc
cc
ce
ep
pt
to
or
r
A
AC
CE
E
SSO
OC
CK
K
CCo
on
nn
ne
ec
ct
to
or
r
AAC
CE
E
SSO
OC
CK
K
SSt
tr
re
ea
am
m
A
AC
CE
E
LLS
SO
OC
CK
K
CCO
OD
Dg
gr
ra
am
m
AAC
CE
E
LLS
SO
OC
CK
K
DDg
gr
ra
am
m
AAC
CE
E
LLS
SO
OC
CK
K
CCo
on
nn
ne
ec
ct
to
or
r
AAC
CE
E
LLS
SO
OC
CK
K
AAc
cc
ce
ep
pt
to
or
r
AAC
CE
E
LLS
SO
OC
CK
K
SSt
tr
re
ea
am
m
ACE
SOCK
Dgram
Mcast
VanderbiltUniversity
71
AdvancedACETutorialDouglasC.Schmidt
EnhancePortabilitywithParameterizedTypes
OS KERNEL
PROTOCOL MECHANISMS
(
TCP/IP,
OSI, ETC.)
USER
SPACE
DISTRIBUTED
APPLICATION
1
APPLICATION
1
DISTRIBUTED
APPLICATION
3
APPLICATION
3
DISTRIBUTED
APPLICATION
2
APPLICATION
2
KERNEL
SPACE
BSD SOCKET
API
COMMON INTERFACE
(
PARAMETERIZED TYPES
)
SOCKET
API
SOCK_SAP
BSD SOCKET
API
S
YSTEM
V
TLI API
TLI_SAP
NETWORK
INTERFACE
//ConditionallyselectIPCmechanism.
#ifdefined(USE_SOCKETS)
typedefACE_SOCK_AcceptorPEER_ACCEPTOR;
#elifdefined(USE_TLI)
typedefACE_TLI_AcceptorPEER_ACCEPTOR;
#endif//USE_SOCKETS.
intmain(void)
{
//...
//Invokewithappropriate
//networkprogramminginterface.
echo_server<PEER_ACCEPTOR>(port);
}
SwitchingwholesalebetweensocketsandTLIsimplyrequires
instantiatingadifferentACEC++wrapperfacade
VanderbiltUniversity
72
AdvancedACETutorialDouglasC.Schmidt
InlinePerformanceCriticalMethods
Inliningistimeandspaceefficientsincekeymethodsareveryshort:classACE_SOCK_Stream:publicACE_SOCK
{
public:
ssize_tsend(constvoid*buf,size_tn)
{
returnACE_OS::send(this->get_handle(),buf,n);
}
ssize_trecv(void*buf,size_tn)
{
returnACE_OS::recv(this->get_handle(),buf,n);
}
};
VanderbiltUniversity
73
AdvancedACETutorialDouglasC.Schmidt
DefineAuxiliaryClassestoHideError-ProneDetails
StandardCsocketaddressingisawkwardanderror-prone
￿
e.g.
,easytoneglecttozero-outasockaddr_inorconvertport
numberstonetworkbyte-order,etc.
ACEC++Socketwrapperfacadesdefineclassestohandledetails classACE_INET_Addr:publicACE_Addr{public:
ACE_INET_Addr(u_shortport,longip_addr=0){
memset(&this->inet_addr_,0,sizeofthis->inet_addr_);
this->inet_addr_.sin_family=AF_INET;
this->inet_addr_.sin_port=htons(port);
memcpy(&this->inet_addr_.sin_addr,&ip_addr,sizeofip_addr);
}
//...
private:
sockaddr_ininet_addr_;
};
VanderbiltUniversity
74
AdvancedACETutorialDouglasC.Schmidt
DemultiplexingandDispatchingEvents
￿
Problem
–Theloggingservermustprocessseveraldifferenttypesofevents
simultaneouslyfromdifferentsourcesofevents
￿
Forces
–Multi-threadingisnotalwaysavailable
–Multi-threadingisnotalwaysefficient
–Multi-threadingcanbeerror-prone
–Tightlycouplingeventdemuxingwithserver-specificlogicis
inflexible
￿
Solution
–Usethe
Reactor
patterntodecoupleeventdemuxing/dispatching
fromserver-specificprocessing
VanderbiltUniversity
75
AdvancedACETutorialDouglasC.Schmidt
TheReactorPattern
Reactor
handle_events()
register_handler(h)
remove_handler(h)
select (handles);
foreach h in handles loop
table[h].handle_event(type)
end loop
Event Handler
handle_event(type)
get_handle()
handlers
Handle
owns
uses
notifies
Concrete
Event
Handler
Synchronous Event
Demultiplexer
select()
1
N
www.cs.wustl.edu/˜schmidt/
POSA/
Intent
￿
Demuxes&dispatches
requeststhatare
delieveredconcurrency
toanapplicationbyone
ormoreclients
ForcesResolved
￿
Seriallydemuxevents
synchronously
&
efficiently
￿
Extendapplications
withoutchanging
demuxingcode
VanderbiltUniversity
76
AdvancedACETutorialDouglasC.Schmidt
CollaborationintheReactorPattern
main
program
INITIALIZE
REGISTER HANDLER
callback :
Concrete
Event_Handler
START EVENT LOOP
DATA ARRIVES
OK TO SEND
Reactor
handle_events()
FOREACH EVENT DO
handle_input()
select()
Reactor()
register_handler(callback)
handle_output()
SIGNAL ARRIVES
TIMER EXPIRES
handle_signal()
handle_timeout()
get_handle()
EXTRACT HANDLE
REMOVE HANDLER
remove_handler(callback)
INITIALIZATION
MODE
EVENT HANDLING
MODE
handle_close()
CLEANUP
￿
Note
inversionof
control
￿
Alsonotehow
long-running
eventhandlers
candegrade
qualityofservice
sincecallbacks
“steal”Reactor’s
threadof
control...
VanderbiltUniversity
77
AdvancedACETutorialDo
StructureandImplementations
oftheACEReactorFramework
Reactorframeworkparticipants
ACE_Reactor
ACE_Event_Handler
ACE_Timer_Queue
ACE_Time_Value
Application Event
Handler
0..1
CommonReactorimplementationsinACE
ACE_Reactor_Impl
ACE_Select_Reactor_Impl
ACE_TP_Reactor
ACE_WFMO_Reactor
ACE_Select_Reactor_T
TOKEN
ACE_Reactor
1
ACE_Select_Reactor
«bind»
<ACE_Select_Reactor_Token>
VanderbiltUniversity
AdvancedACETutorialDo
UsingtheACEReactorFramework
intheLoggingServer
REGISTERED
OBJECTS
FRAMEWORK
LEVEL
KERNEL
LEVEL
APPLICATION
LEVEL
1: handle_input()
5: handle_input()
6: recv(msg)
7:process(msg)
2: sh = new Logging_Handler
3: accept (sh->peer())
4: sh->open()
OS EVENT DEMULTIPLEXING INTERFACE
: Reactor
:Timer
Queue
: Handle
Table
: Event
Handler
: Logging
Handler
: Event
Handler
: Logging
Handler
: Event
Handler
: Logging
Acceptor
Benefits
￿
Straightforwardto
program
￿
Concurrencycontrol
iseasy
Liabilities
￿
Callbacksare“brittle”
￿
Can’tleverage
multi-processors
VanderbiltUniversity
AdvancedACETutorialDouglasC.Schmidt
AddressingAcceptorEndpointConnection
andInitializationChallenges
￿
Problem
–The
communication
protocolusedbetweenapplicationsisoften
orthogonaltoits
connectionestablishment
and
servicehandler
initialization
protocols
￿
Forces
–Low-levelconnectionAPIsareerror-proneandnon-portable
–Separating
initialization
from
processing
increasessoftwarereuse
￿
Solution
–Usethe
Acceptor
patterntodecouplepassiveconnection
establishmentandconnectionhandlerinitializationfromthe
subsequentloggingprotocol
VanderbiltUniversity
80
AdvancedACETutorialDo
TheAcceptor-ConnectorPattern
(AcceptorRole)
Svc
Handler
peer_stream_
open()
Acceptor
peer_acceptor_
accept()
Svc Handler
Reactor
APPLICATION
-
DEFINED
APPLICATION
-
INDEPENDENT
ACTIVATES
www.cs.wustl.edu/˜schmidt/POSA/
IntentofAcceptorRole
￿
Decouplethepassive
connectionand
initializationofapeer
serviceinadistributed
systemfromthe
processingperformed
oncethepeerserviceis
connectedand
initialized
Forcesresolved
￿
Reusepassive
connectionsetup
andservice
initializationcode
￿
Ensurethat
acceptor-mode
handlesaren’tused
toread/writedata
VanderbiltUniversity
AdvancedACETutorialDo
StructureoftheACE
Acceptor-ConnectorFramework
ACE_Svc_Handler
PEER_STREAM,
SYNCH_STRATEGY
ACE_Acceptor
SVC_HANDLER,
PEER_ACCEPTOR
ACE_Connector
SVC_HANDLER,
PEER_CONNECTOR
Application
Service
«bind»
ACE_Event_Handler
ACE_Task
SYNCH_STRATEGY
Frameworkcharacteristics
￿
UsesC++parameterizedtypestostrategizeIPC
andserviceaspects
￿
UsesTemplateMethodpatterntostrategize
creation,connectionestablishment,and
concurrencypolicies
VanderbiltUniversity
AdvancedACETutorialDo
UsingtheACE_Acceptor
intheLoggingServer
PASSIVE
LISTENER
ACTIVE
CONNECTIONS
1: handle_input()
2: sh = make_svc_handler()
3: accept_svc_handler(sh)
4: activate_svc_handler(sh)
: Reactor
: Acceptor
: Logging
Acceptor
: Svc
Handler
: Logging
Handler
: Svc
Handler
: Logging
Handler
: Svc
Handler
: Logging
Handler
: Svc
Handler
: Logging
Handler
￿
TheACE_Acceptorisafactory
–i.e.,itcreates,connects,andactivatesan
ACE_Svc_Handler
￿
There’softenoneACE_Acceptor
per-service/per-port
VanderbiltUniversity
AdvancedACETutorialDo
ACE_AcceptorClassPublicInterface
template<classSVC_HANDLER,//Serviceaspect
classPEER_ACCEPTOR>//IPCaspect
classACE_Acceptor:publicACE_Service_Object
{
//Inheritsindirectlyfrom<ACE_Event_Handler>
public:
//Initialization.
virtualintopen
(typenameconstPEER_ACCEPTOR::PEER_ADDR&,
ACE_Reactor*=ACE_Reactor::instance());
//TemplateMethod.
virtualinthandle_input(ACE_HANDLE);
protected:
//Factorymethodcreatesaservicehandler.
virtualSVC_HANDLER*make_svc_handler(void);
//Acceptanewconnection.
virtualintaccept_svc_handler(SVC_HANDLER*);
//Activateaservicehandler.
virtualintactivate_svc_handler(SVC_HANDLER*);
private:
//AcceptorIPCconnectionstrategy.
PEER_ACCEPTORpeer_acceptor_;
};
VanderbiltUniversity
AdvancedACETutorialDo
ACE_AcceptorClassImplementation
//Shorthandnames.
#defineSHSVC_HANDLER
#definePAPEER_ACCEPTOR
//TemplateMethodthatcreates,connects,
//andactivatesservicehandlers.
template<classSH,classPA>int
ACE_Acceptor<SH,PA>::handle_input(ACE_HANDLE)
{
//Factorymethodthatmakesaservicehandler.
SH*svc_handler=make_svc_handler();
//Accepttheconnection.
accept_svc_handler(svc_handler);
//Delegatecontroltotheservicehandler.
activate_svc_handler(svc_handler);
}
VanderbiltUniversity
AdvancedACETutorialDouglasC.Schmidt
TheTemplateMethodPattern
Concrete
Class
primitive_operation1()
primitive_operation2()
...
primitive_operation1()
...
primitive_operation2()
...
Abstract
Class
template_method()
primitive_operation1()
primitive_operation2()
Intent
￿
Definetheskeletonof
analgorithminan
operation,deferring
somestepsto
subclasses
Gammaetal.,
Design
Patterns:Elementsof
ReusableObject-Oriented
Software
AW,’94
VanderbiltUniversity
86
AdvancedACETutorialDouglasC.Schmidt
UsingtheTemplateMethodPatternin
theACEAcceptorImplementation
Acceptor
handle_input()
make_svc_handler()
accept_svc_handler()
activate_svc_handler()
...
make_svc_handler()
...
accept_svc_handler()
...
activate_svc_handler()
My
Acceptor
make_svc_handler()
activate_svc_handler()
Benefits
￿
Straightforwardto
programviainheritance
anddynamicbinding
Liabilities
￿
Designis“brittle”and
cancause“explosion”of
subclassesdueto
“whitebox”design
VanderbiltUniversity
87
AdvancedACETutorialDouglasC.Schmidt
TheStrategyPattern
Strategy
algorithm_interface()
Concrete
Strategy A
algorithm_interface()
STRATEGY
Concrete
Strategy B
algorithm_interface()
Concrete
Strategy C
algorithm_interface()
Context
context_interface()
Intent
￿
Defineafamilyof
algorithms,encapsulate
eachone,andmake
theminterchangeable
Gammaetal.,
Design
Patterns:Elementsof
ReusableObject-Oriented
Software
AW,’94
VanderbiltUniversity
88
AdvancedACETutorialDouglasC.Schmidt
UsingtheStrategyPatternin
theACEAcceptorImplementation
Thread
Strategy
Process
Strategy
Reactive
Strategy
Acceptor
handle_input()
sh = create_svc_handler ()
...
accept_svc_handler (sh)
...
1: activate_svc_handler(sh)
...
2: activate_svc_handler(sh)
<<delegates>>
activate_svc_handler()
Concurrency
Strategy
Benefits
￿
More
extensibledue
to“blackbox”
design
Liabilities
￿
Morecomplex
andharderto
developinitially
VanderbiltUniversity
89
AdvancedACETutorialDo
ACE_AcceptorTemplateMethod
HookImplementations
Templatemethodhookscanbeoverridden
//Factorymethodforcreatingaservicehandler.
template<classSH,classPA>SH*
ACE_Acceptor<SH,PA>::make_svc_handler(ACE_HANDLE)
returnnewSH;//Defaultbehavior.
}
//Acceptconnectionsfromclients.
template<classSH,classPA>int
ACE_Acceptor<SH,PA>::accept_svc_handler(SH*sh)
{
peer_acceptor_.accept(sh->peer());
}
//Activatetheservicehandler.
template<classSH,classPA>int
ACE_Acceptor<SH,PA>::activate_svc_handler(SH*sh)
{
if(sh->open()==-1)
sh->close();
}
VanderbiltUniversity
AdvancedACETutorialDo
ACE_AcceptorInitialization
Implementation
NotehowthePEER_ACCEPTOR’sopen()method
hidesallthedetailsassociatedwithpassively
initializingcommunicationendpoints
//Initialization.
template<classSH,classPA>int
ACE_Acceptor<SH,PA>::open
(typenameconstPA::PEER_ADDR&addr,
ACE_Reactor*reactor)
{
//Forwardinitializationtotheconcrete
//peeracceptor.
peer_acceptor_.open(addr);
//RegisterwithReactor.
reactor->register_handler
(this,ACE_Event_Handler::ACCEPT_MASK);
}
VanderbiltUniversity
AdvancedACETutorialDo
ACE_Svc_HandlerClassPublic
Interface
NotehowIPCandsynchronizationaspectsare
strategized
template<classPEER_STREAM,//IPCaspect
classSYNCH_STRAT>//Synchaspect
classACE_Svc_Handler
:publicACE_Task<SYNCH_STRAT>
//Taskis-aService_Object,
//whichis-anEvent_Handler
{
public:
//Constructor.
ACE_Svc_Handler(Reactor*=
ACE_Reactor::instance());
//Activatethehandler(calledbythe
.//<ACE_Acceptor>or<ACE_Connector>).
virtualintopen(void*);
//ReturnunderlyingIPCmechanism.
PEER_STREAM&peer(void);
//...
private:
PEER_STREAMpeer_;//IPCmechanism.
virtual˜ACE_Svc_Handler(void);
};
VanderbiltUniversity
AdvancedACETutorialDouglasC.Schmidt
ACE_Svc_HandlerImplementation
#definePSPEER_STREAM
#defineSSSYNCH_STRAT
template<classPS,classSS>
ACE_Svc_Handler<PS,SS>::ACE_Svc_Handler
(ACE_Reactor*r):ACE_Service_Object(r)
{}
template<classPS,classSS>
intACE_Svc_Handler<PS,SS>::open
(void*){
//Enablenon-blockingI/O.
peer().enable(ACE_NONBLOCK);
//RegisterhandlerwiththeReactor.
reactor()->register_handler
(this,ACE_Event_Handler::READ_MASK);
}
￿
Bydefault,a
ACE_Svc_Handler
objectisregistered
withthesingleton
ACE_Reactor
–Thismakesthe
service“reactive”
sothatnoother
synchronization
mechanismsare
necessary
VanderbiltUniversity
93
AdvancedACETutorialDo
ObjectDiagramforOOLoggingServer
Service
Config
SERVER
SERVER
LOGGING
DAEMON
CONNECTION
REQUEST
REMOTE
CONTROL
OPERATIONS
CLIENT
LOGGING
RECORDS
CLIENT
CLIENT
CLIENT
Logging
Handler
Logging
Handler
Logging
Acceptor
Service
Manager
Service
Repository
Reactor
VanderbiltUniversity
AdvancedACETutorialDo
TheLogging_Handlerand
Logging_AcceptorClasses
//PerformsI/Owithclientloggingdaemons.
classLogging_Handler:public
ACE_Svc_Handler<ACE_SOCK_Acceptor::PEER_STREAM,
//Trait!
ACE_NULL_SYNCH>
{
public:
//Recvandprocessremoteloggingrecords.
virtualinthandle_input(ACE_HANDLE);
};
//Logging_Handlerfactory.
classLogging_Acceptor:public
ACE_Acceptor<Logging_Handler,ACE_SOCK_Acceptor>
{
public:
//Dynamiclinkinghooks.
virtualintinit(intargc,char*argv[]);
virtualintfini(void);
};
VanderbiltUniversity
AdvancedACETutorialDouglasC.Schmidt
DesignInterlude:ParameterizingIPCMechanisms
￿
Q:
HowcanyouswitchbetweendifferentIPCmechanisms?
￿
A:ByparameterizingIPCMechanismswithC++Templates,
e.g.
:
#ifdefined(ACE_USE_SOCKETS)
typedefACE_SOCK_AcceptorPEER_ACCEPTOR;
#elifdefined(ACE_USE_TLI)
typedefACE_TLI_AcceptorPEER_ACCEPTOR;
#endif/*ACE_USE_SOCKETS*/
classLogging_Handler:public
ACE_Svc_Handler<PEER_ACCEPTOR::PEER_STREAM,//Trait!
ACE_NULL_SYNCH>
{/*.../*};
classLogging_Acceptor:public
ACE_Acceptor<Logging_Handler,PEER_ACCEPTOR>
{/*...*/};
VanderbiltUniversity
96
AdvancedACETutorialDouglasC.Schmidt
Logging_HandlerInputMethod
Callbackroutinethatreceivesloggingrecords int
Logging_Handler::handle_input(ACE_HANDLE)
{
//Callexistingfunctiontorecv
//loggingrecordandprinttostdout.
ssize_tn=
handle_log_record(peer().get_handle(),
ACE_STDOUT);
if(n>0)
//Countthe#ofloggingrecords
++request_count;
returnn<=0?-1:0;
}
￿
Implementationof
application-specific
loggingmethod
￿
Thisisthemaincode
suppliedbya
developer!
VanderbiltUniversity
97
AdvancedACETutorialDo
Logging_AcceptorInitialization
andTermination
//AutomaticallycalledwhenaLogging_Acceptor
//objectislinkeddynamically.
Logging_Acceptor::init(intargc,char*argv[])
{
ACE_Get_Optget_opt(argc,argv,"p:",0);
ACE_INET_Addraddr(DEFAULT_PORT);
for(intc;(c=get_opt())!=-1;)
switch(c){
case’p’:
addr.set(atoi(getopt.optarg));
break;
default:
break;
}
//Initializeendpointandregister
//withthe<ACE_Reactor>.
open(addr,ACE_Reactor::instance());
}
//Automaticallycalledwhenobjectisunlinked.
Logging_Acceptor::fini(void){handle_close();}
VanderbiltUniversity
AdvancedACETutorialDouglasC.Schmidt
PuttingthePiecesTogetheratRun-time
￿
Problem
–Prematurelycommittingourselvestoaparticularloggingserver
configurationisinflexibleandinefficient
￿
Forces
–Itisusefultobuildsystemsby“scripting”components
–Certaindesigndecisionscan’tbemadeefficientlyuntilrun-time
–Itisabadideatoforceusersto“pay”forcomponentstheydonot
use
￿
Solution
–Usethe
ComponentConfigurator
patterntoassemblethedesired
loggingservercomponentsdynamically
VanderbiltUniversity
99
AdvancedACETutorialDouglasC.Schmidt
TheComponentConfiguratorPattern
Reactor
1
n
Concrete
Component
REACTIVE
LAYER
CONFIGURATION
LAYER
APPLICATION
LAYER
1
1
Component
Config
n
Component
A
suspend()
resume()
init()
fini()
info()
1
Component
Repository
1
Event
Handler
Intent
￿
Decouplesthe
implementationofservices
fromthetimewhentheyare
configured
ForcesResolved
￿
Reduceresourceutilization
￿
Supportdynamic
(re)configuration
www.cs.wustl.edu/
˜schmidt/POSA/
VanderbiltUniversity
100
AdvancedACETutorialDo
StructureoftheACEService
ConfiguratorFramework
ACE_Service_Object
ACE_Service_Config
ACE_Service_Repository
ACE_Service_Repository_Iterator
ACE_Event_Handler
Application Service
Frameworkcharacteristics
￿
ACE_Service_Configusesavariantofthe
Monostatepattern
￿
Canbeaccessedeitherviaascriptor
programmatically
VanderbiltUniversity
AdvancedACETutorialDo
UsingtheACEServiceConfigurator
FrameworkfortheLoggingServer
SERVICE
CONFIGURATOR
RUNTIME
Service
Repository
Service
Object
Thread
Pool
Logger
DLL
S
Service
Object
Thread
Logger
dynamic Logger Service_Object *
logger:make_Logger() "-p 2001"
svc.conf
FILE
Service
Object
Reactive
Logger
Reactor
Service
Config
￿
TheexistingLoggingServerserviceis
single-threaded
￿
Otherversionscouldbemulti-threaded
￿
Notehowwecanscriptthisviathesvc.conf
file
VanderbiltUniversity
AdvancedACETutorialDouglasC.Schmidt
DynamicallyLinkingaService
Dynamicallylinkedfactoryfunction
thatallocatesanew
Logging_Acceptor
extern"C"
ACE_Service_Object*
make_Logger(void);
ACE_Service_Object*
make_Logger(void)
{
returnnewLogging_Acceptor;
//Frameworkautomatically
//deletesmemory.
}
￿
Application-specificfactory
functionusedtodynamically
createaservice
￿
Themake_Logger()function
providesa
hook
betweenan
application-specific
service
andthe
application-independent
ACE
mechanisms
–ACEhandlesallmemory
allocationanddeallocation
VanderbiltUniversity
103
AdvancedACETutorialDouglasC.Schmidt
ServiceConfiguration
Theloggingserviceisconfigured
viascriptinginasvc.conffile:
%cat./svc.conf
#Dynamicallyconfigure
#theloggingservice
dynamicLogger
Service_Object*
logger:_make_Logger()"-p2001"
#Note,.dllor.sosuffix
#addedtothelogger
#automatically
Genericevent-loopto
dynamicallyconfigureservice
daemons
intmain(intargc,char*argv[])
{
//Initializethedaemonand
//configureservices
ACE_Service_Config::open(argc,
argv);
//Runforever,performingthe
//configuredservices
ACE_Reactor::instance()->
run_reactor_event_loop();
/*NOTREACHED*/
}
VanderbiltUniversity
104
AdvancedACETutorialDouglasC.Schmidt
StateChartfortheServiceConfiguratorFramework
INITIALIZED
CONFIGURE/
Service_Config::process_directives()
NETWORK
EVENT/
Reactor::dispatch()
RECONFIGURE/
Service_Config::process_directives()
SHUTDOWN/
Service_Config::close()
AWAITING
EVENTS
CALL
HANDLER/
Event_Handler::handle_input()
IDLE
PERFORM
CALLBACK
START
EVENT
LOOP/
Reactor::run_event_loop()
VanderbiltUniversity
105
AdvancedACETutorialDouglasC.Schmidt
AdvantagesofOOLoggingServer
￿
TheOOarchitectureillustratedthusfardecouples
application-specificservicefunctionalityfrom:
–Timewhenaserviceisconfiguredintoaprocess
–Thenumberofservicesper-process
–ThetypeofIPCmechanismused
–Thetypeofeventdemultiplexingmechanismused
￿
Wecanusethetechniquesdiscussedthusfartoextendapplications
without
:

Modifying
,
recompiling
,and
relinking
existingcode

Terminating
and
restarting
executingdaemons
￿
TheremainderoftheLoggingServerslidesexamineasetof
techniquesfordecouplingfunctionalityfrom
concurrency
mechanisms,aswell
VanderbiltUniversity
106
AdvancedACETutorialDouglasC.Schmidt
ConcurrentOOLoggingServer
￿
ThestructureoftheLoggingServercanbenefitfromconcurrent
executiononamulti-processorplatform
￿
ThissectionexaminesACEC++classesandpatternsthatextend
theloggingservertoincorporateconcurrency
–Notehowmostextensionsrequireminimalchangestothe
existingOOarchitecture...
￿
ThisexamplealsoillustratesadditionalACEcomponentsinvolving
synchronizationandmulti-threading
VanderbiltUniversity
107
AdvancedACETutorialDo
ConcurrentOOLogging
ServerArchitecture
NETWORK
SERVER
LOGGING SERVER
Logging
Handler
Logging
Handler
Logging
Acceptor
1: SOCK
Acceptor
2: accept()
4: handle_input()
5: spawn()
3: connect()
6: send()
7: recv()
8: write()
CLIENT
A
CLIENT
B
6: send()
7: recv()
8: write()
Reactor
Runseachclientconnectioninaseparatethread
VanderbiltUniversity
AdvancedACETutorialDouglasC.Schmidt
Pseudo-codeforConcurrentServer
￿
Pseudo-codeformulti-threadedLogging_Handlerfactory
LoggingServer voidhandler_factory(void){
initializeacceptorendpoint
foreach(pendingconnectionevent){
acceptconnection
spawnathreadtohandleconnectionand
runlogging_handler()entrypoint
}
}
￿
Pseudo-codeforlogging_handler()function
voidlogging_handler(void){
foreach(incomingloggingrecordsfromclient)
callhandle_log_record()
exitthread
}
VanderbiltUniversity
109
AdvancedACETutorialDouglasC.Schmidt
ConcurrencyOverview
THREADS
PROCESS
SHARED ADDRESS SPACE
￿
Athreadisasequenceof
instructionsexecutedinone
ormoreprocesses

Oneprocess
￿
stand-alonesystems

Morethanoneprocess
￿
distributedsystems
TraditionalOSprocessescontainasinglethreadofcontrol
￿
Thissimplifiesprogrammingsinceasequenceofexecutionstepsis
protectedfromunwantedinterferencebyotherexecution
sequences...
VanderbiltUniversity
110
AdvancedACETutorialDouglasC.Schmidt
TraditionalApproachestoOSConcurrency
1.Devicedriversandprogramswithsignalhandlersutilizealimited
formof
concurrency
￿
e.g.
,asynchronousI/O
￿
Notethat
concurrency
encompassesmorethan
multi-threading
...
2.ManyexistingprogramsutilizeOSprocessestoprovide
“coarse-grained”concurrency
￿
e.g.
,
–Client/serverdatabaseapplications
–StandardnetworkdaemonslikeUNIX
INETD
￿
MultipleOSprocessesmaysharememoryviamemorymapping
orsharedmemoryandusesemaphorestocoordinateexecution
￿
TheOSkernelschedulerdictatesprocessbehavior
VanderbiltUniversity
111
AdvancedACETutorialDouglasC.Schmidt
EvaluatingTraditionalOSProcess-basedConcurrency
￿
Advantages

Easytokeepprocessesfrominterfering
￿
Aprocesscombines
security
,
protection
,and
robustness
￿
Disadvantages

Complicatedtoprogram
,
e.g.
,
–Signalhandlingmaybetricky
–Sharedmemorymaybeinconvenient
￿
Inefficient
–TheOSkernelisinvolvedinsynchronizationandprocess
management
–Difficulttoexertfine-grainedcontroloverschedulingandpriorities
VanderbiltUniversity
112
AdvancedACETutorialDouglasC.Schmidt
ModernOSConcurrency
￿
ModernOSplatformstypicallyprovideastandardsetofAPIsthat
handle
–Process/threadcreationanddestruction
–Varioustypesofprocess/threadsynchronizationandmutual
exclusion
–Asynchronousfacilitiesforinterruptinglong-running
processes/threadstoreporterrorsandcontrolprogrambehavior
￿
Oncetheunderlyingconceptsaremastered,it’srelativelyeasyto
learndifferentconcurrencyAPIs

e.g.
,traditionalUNIXprocessoperations,Solaristhreads,POSIX
pthreads,WIN32threads,Javathreads,etc.
VanderbiltUniversity
113
AdvancedACETutorialDouglasC.Schmidt
LightweightConcurrency
￿
Modernoperatingsystemsprovidelightweightmechanismsthat
manageandsynchronizemultiplethreads
within
aprocess
–Somesystemsalsoallowthreadstosynchronize
across
multiple
processes
￿
Benefitsofthreads
1.
Relativelysimpleandefficienttocreate,control,synchronize,and
collaborate
–Threadssharemanyprocessresourcesbydefault
2.
Improveperformancebyoverlappingcomputationand
communication
–Threadsmayalsoconsumelessresourcesthanprocesses
3.
Improveprogramstructure

e.g.
,comparedwithusingasynchronousI/O
VanderbiltUniversity
114
AdvancedACETutorialDo
Example:Single-threadedvs.
Multi-threadedApplications
MULTI
-
THREADED
RPC
CLIENT
SERVER
CLIENT
USER
KERNEL
THREAD
BLOCKED
USER
KERNEL
SERVICE
EXECUTES
REQUEST
RESPONSE
SERVER
CLIENT
USER
KERNEL
USER
KERNEL
SERVICE
EXECUTES
REQUEST
RESPONSE
SERVER
USER
KERNEL
SERVICE
EXECUTES
REQUEST
RESPONSE
SINGLE
-
THREADED
RPC
VanderbiltUniversity
AdvancedACETutorialDouglasC.Schmidt
HardwareandOSConcurrencySupport
THREAD
PE
PROCESSING
ELEMENT
LIGHTWEIGHT
PROCESS
LWP
UNIX
PROCESS
PE
PE
PE
PE
PE
PE
PE
PE
SHARED MEMORY
KERNEL
-
LEVEL
USER
-
LEVEL
LWP
LWP
LWP
LWP
LWP
LWP
LWP
Fourtypical
abstractions
1.
Application
threads
2.
Lightweight
processes
3.
Kernelthreads
4.
Processing
elements
VanderbiltUniversity
116
AdvancedACETutorialDouglasC.Schmidt
ApplicationThreads
Mostprocessresourcesare
equallyaccessibletoallthreads
inaprocess,
e.g.
,
￿
Virtualmemory
￿
Userpermissionsandaccess
controlprivileges
￿
Openfiles
￿
Signalhandlers
Eachthreadalsocontainsunique
information,
e.g.
,
￿
Identifier
￿
Registerset
(
e.g.
,PCandSP)
￿
Run-timestack
￿
Signalmask
￿
Priority
￿
Thread-specificdata
(
e.g.
,
errno)
Note,thereisnoMMUprotectionforthreadsinasingleprocess
VanderbiltUniversity
117
AdvancedACETutorialDouglasC.Schmidt
Kernel-levelvs.User-levelThreads
￿
Applicationandsystemcharacteristicsinfluencethechoiceof
user-level
vs.
kernel-level
threading
￿
Ahighdegreeof“virtual”applicationconcurrencyimpliesuser-level
threads(
i.e.
,unboundthreads)

e.g.
,desktopwindowingsystemonauni-processor
￿
Ahighdegreeof“real”applicationparallelismimplieslightweight
processes(LWPs)(
i.e.
,boundthreads)

e.g.
,video-on-demandserverormatrixmultiplicationona
multi-processor
VanderbiltUniversity
118
AdvancedACETutorialDouglasC.Schmidt
OverviewofOSSynchronizationMechanisms
￿
Threadsshareresourcesinaprocessaddressspace
￿
Therefore,theymustuse
synchronizationmechanisms
tocoordinate
theiraccesstoshareddata
￿
TraditionalOSsynchronizationmechanismsareverylow-level,
tedioustoprogram,error-prone,andnon-portable
￿
ACEencapsulatesthesemechanismswithwrapperfacadesand
higher-levelpatterns/components
VanderbiltUniversity
119
AdvancedACETutorialDouglasC.Schmidt
CommonOSSynchronizationMechanisms
￿
Mutualexclusion(mutex)locks
–Serializethreadaccesstoasharedresource
￿
Countingsemaphores
–Synchronizethreadexecution
￿
Readers/writer(R/W)locks
–Serializeresourcesthataresearchedmorethanchanged
￿
Conditionvariables
–Usedtoblockthreadsuntilshareddatachangesstate
￿
Filelocks
–System-wideR/Wlocksaccessedbyprocesses
VanderbiltUniversity
120
AdvancedACETutorialDouglasC.Schmidt
AdditionalACESynchronizationMechanism
￿
Events

Gates
and
latches
￿
Barriers
–Allowsthreadstosynchronizetheircompletion
￿
Token
–ProvidesFIFOschedulingorder
￿
Task
–Provideshigher-level“activeobject”forconcurrentapplications
￿
Thread-specificstorage
–Low-overhead,contention-freestorage
VanderbiltUniversity
121
AdvancedACETutorialDo
ConcurrencyMechanismsinACE
Token
ADVANCED SYNCH
Barrier
Condition
MUTEX
Null
Condition
CONDITIONS
Task
SYNCH
ACTIVE
OBJECTS
Thread
Manager
MANAGERS
Process
Manager
Guard
GUARDS
Read
Guard
Write
Guard
Atomic
Op
LOCK
TYPE
TSS
TYPE
Thread
Mutex
Null
Mutex
RW
Mutex
Events
Semaphore
SYNCH WRAPPERS
File
Lock
Process
Mutex
Thread
Mutex
Thread
Semaphore
Process
Semaphore
￿
AllACEConcurrencymechanismsareportedto
allOSplatforms
￿
www.cs.wustl.edu/˜schmidt/ACE/
book1/
VanderbiltUniversity
AdvancedACETutorialDouglasC.Schmidt
AddressingLoggerServerConcurrencyChallenges
￿
Problem
–Multi-threadedloggingserversmaybenecessarywhen
single-threadedreactiveserversinefficient,non-scalable,or
non-robust
￿
Forces
–Multi-threadingcanbeveryhardtoprogram
–Nosinglemulti-threadingmodelisalwaysoptimal
￿
Solution
–Usethe
ActiveObject
patterntoallowmultipleconcurrentlogging
serveroperationsusinganOOprogrammingstyle
VanderbiltUniversity
123
AdvancedACETutorialDo
ACESupportforActiveObjects
:
TASK
STATE
:

Message
Queue
ACTIVE
t
2
:
Task
2: enqueue (msg)
1: put (msg)
t
1
:
Task
t
3
:
Task
6: put (msg)
3: svc ()
4: dequeue (msg)
5: do_work(msg)
ACTIVE
ACTIVE
:
TASK
STATE
:

Message
Queue
:
TASK
STATE
:

Message
Queue
TheACETaskframeworkcanbeusedto
implementthecompleteActiveObjectpatternor
lighterweightsubsets
VanderbiltUniversity
AdvancedACETutorialDouglasC.Schmidt
TheACETaskFramework
￿
AnACE_Taskbindsaseparatethreadofcontroltogetherwithan
object’sdataandmethods
–Multipleactiveobjectsmayexecuteinparallelinseparate
lightweightorheavyweightprocesses
￿
ACE_Taskobjectscommunicatebypassingtypedmessagesto
otherACE_Taskobjects
–EachACE_Taskmaintainsaqueueofpendingmessagesthatit
processesin
priorityorder
￿
ACE_Taskisalow-levelmechanismtosupportactiveobjects
VanderbiltUniversity
126
AdvancedACETutorialDo
StructureoftheACETaskFramework
ACE_Thread_Manager
ACE_Task
0..1
*
SYNCH
ACE_Message_Queue
SYNCH
ACE_Message_Block
*
1
ACE_Service_Object
ACE_Event_Handler
Frameworkcharacteristics
1.ACE_TaskscanregisterwithanACE_Reactor
2.Theycanbedynamicallylinked
3.Theycanqueuedata
4.Theycanrunasactiveobjectsin1ormore
threads
VanderbiltUniversity
AdvancedACETutorialDouglasC.Schmidt
TheACE_TaskClassPublicInterface
template<classSYNCH_STRAT>
//Synchronizationaspect
classACE_Task:publicACE_Service_Object{
public:
//Initialization/terminationhooks.
virtualintopen(void*args=0)=0;
virtualintclose(u_long=0)=0;
//Transfermsgtoqueueforimmediateprocessing.
virtualintput(ACE_Message_Block*,ACE_Time_Value*=0)=0;
//Runbyadaemonthreadfordeferredprocessing.
virtualintsvc(void)=0;
//Turntaskintoactiveobject.
intactivate(longflags,intthreads=1);
VanderbiltUniversity
128
AdvancedACETutorialDouglasC.Schmidt
ACE_TaskClassProtectedInterface
Manyofthefollowingmethodsareusedbyput()andsvc()
//Accessorstointernalqueue.
ACE_Message_Queue<SYNCH_STRAT>*msg_queue(void);
voidmsg_queue(ACE_Message_Queue<SYNCH_STRAT>*);
//Accessorstothreadmanager.
ACE_Thread_Manager*thr_mgr(void);
voidthr_mgr(ACE_Thread_Manager*);
//Insertmessageintothemessagelist.
intputq(ACE_Message_Block*,ACE_Time_Value*tv=0);
//Extractthefirstmessagefromthelist(blocking).
intgetq(ACE_Message_Block*&mb,ACE_Time_Value*tv=0);
//Hookintotheunderlyingthreadlibrary.
staticvoid*svc_run(ACE_Task<SYNCH_STRAT>*);
VanderbiltUniversity
129
AdvancedACETutorialDouglasC.Schmidt
DesignInterlude:CombiningThreads&C++Objects
￿
Q:
Whatisthesvc_run()functionandwhyisitastaticmethod?
￿
A:OSthreadAPIsrequireC-stylefunctionsasentrypoint
￿
TheACETaskframeworkencapsulatesthesvc_run()function
withintheACE_Task::activate()method:
template<classSYNCH_STRAT>int
ACE_Task<SYNCH_STRAT>::activate(longflags,intn_threads){
if(thr_mgr()==NULL)thr_mgr(ACE_Thread_Manager::instance());
thr_mgr()->spawn_n(n_threads,&ACE_Task<SYNCH_STRAT>::svc_run,
(void*)this,flags);
}
11.
.
A
AC
CE
E_
_T
Ta
as
sk
k:
::
:a
ac
ct
ti
iv
va
at
te
e
(
()
)
22.
.
A
AC
CE
E_
_T
Th
hr
re
ea
ad
d_
_M
Ma
an
na
ag
ge
er
r:
::
:s
sp
pa
aw
wn
n



(
(s
sv
vc
c_
_r
ru
un
n,
,
t
th
hi
is
s)
);
;
33.
.
_
_b
be
eg
gi
in
nt
th
hr
re
ea
ad
de
ex
x



(
(0
0,
,
0
0,
,




s
sv
vc
c_
_r
ru
un
n,
,
t
th
hi
is
s,
,




0
0,
,
&
&t
th
hr
re
ea
ad
d_
_i
id
d)
);
;

R
RU
UN
N-
-T
TI
IM
ME
E
TTH
HR
RE
EA
AD
D
S
ST
TA
AC
CK
K
4
4.
.
t
te
em
mp
pl
la
at
te
e
<
<S
SY
YN
NC
CH
H_
_S
ST
TR
RA
AT
TE
EG
GY
Y>
>
v
vo
oi
id
d
*
*


A
AC
CE
E_
_T
Ta
as
sk
k<
<S
SY
YN
NC
CH
H_
_S
ST
TR
RA
AT
TE
EG
GY
Y>
>:
::
:s
sv
vc
c_
_r
ru
un
n




(
(A
AC
CE
E_
_T
Ta
as
sk
k<
<S
SY
YN
NC
CH
H_
_S
ST
TR
RA
AT
TE
EG
GY
Y>
>
*
*t
t)
)
{
{




/
//
/
.
..
..
.




v
vo
oi
id
d
*
*s
st
ta
at
tu
us
s
=
=
t
t-
->
>s
sv
vc
c
(
()
);
;




/
//
/
.
..
..
.




r
re
et
tu
ur
rn
n
s
st
ta
at
tu
us
s;
;
/
//
/
T
Th
hr
re
ea
ad
d
r
re
et
tu
ur
rn
n.
.


}
}
VanderbiltUniversity
130
AdvancedACETutorialDouglasC.Schmidt
Thesvc_run()AdapterFunction
ACE_Task::svc_run()isstaticmethodusedastheentrypointto
executeaninstanceofaserviceconcurrentlyinitsownthread template<classSYNCH_STRAT>void*
ACE_Task<SYNCH_STRAT>::svc_run(ACE_Task<SYNCH_STRAT>*t)
{
//Threadaddedtothr_mgr()automaticallyonentry.
//Runservicehandlerandrecordreturnvalue.
void*status=(void*)t->svc();
t->close(u_long(status));
//Statusbecomes"return"valueofthread...
returnstatus;
//Threadremovedfromthr_mgr()automaticallyonreturn.
}
VanderbiltUniversity
131
AdvancedACETutorialDouglasC.Schmidt
DesignInterlude:Motivation
fortheACE_Thread_Manager
￿
Q:
Howcangroupsofcollaboratingthreadsbemanagedatomically?
￿
A:DeveloptheACE_Thread_Managerclassthat:
–Supportsthenotionof
threadgroups
￿
i.e.
,operationsonallthreadsinagroup
–Implements
barriersynchronization
onthreadexits
–ShieldsapplicationsfromincompatibilitiesbetweendifferentOS
threadlibraries
￿
e.g.
,detachedthreadsandthreadjoins
VanderbiltUniversity
132
AdvancedACETutorialDouglasC.Schmidt
UsingACETaskFrameworkforLoggingServer
Processremoteloggingrecords
byloopinguntiltheclient
terminatesconnection int
Thr_Logging_Handler::svc(void)
{
while(handle_input()!=-1)
//Callexistingfunction
//torecvloggingrecord
//andprinttostdout.
continue;
return0;
}
￿
TheOOimplementationlocalizes
theapplication-specificpartof
theloggingserviceinasingle
point,whileleveragingoff
reusableACEcomponents
￿
Comparewithoriginal,which
borrow’stheReactorthread int
Logging_Handler::handle_input(void)
{
handle_log_record
(peer().get_handle(),
ACE_STDOUT);
//...
}
VanderbiltUniversity
133
AdvancedACETutorialDo
ClassDiagramforConcurrent
OOLoggingServer
Thr
Logging
Acceptor
Thr_Logging_Handler
SOCK_Acceptor
Thr
Logging
Handler
SOCK_Stream
NULL_Synch
Svc
Handler
Acceptor
SVC_HANDLER
PEER_ACCEPTOR
PEER_STREAM
SYNCH
CONNECTION-
ORIENTED
COMPONENTS
APPLICATION
-
SPECIFIC
COMPONENTS
ACE
FRAMEWORK
COMPONENTS
Concurrency
global
Connection
Reactor
<<activates>>
1
n
PEER
ACCEPTOR
PEER
STREAM
IPC_SAP
Stream
Service
Configurator
VanderbiltUniversity
AdvancedACETutorialDo
Thr_Logging_Acceptorand
Thr_Logging_HandlerInterfaces
Templateclassesthatcreate,connect,andactivate
anewthreadtohandleeachclient
classThr_Logging_Handler
:publicLogging_Handler
//Inherits<handle_input>
{
public:
//Overridedefinitionin<ACE_Svc_Handler>
//classtospawnanewthread!Thismethod
//iscalledbythe<ACE_Acceptor>.
virtualintopen(void*);
//Processremoteloggingrecords.
virtualintsvc(void);
};
classThr_Logging_Acceptor:public
ACE_Acceptor<Thr_Logging_Handler,
ACE_SOCK_Acceptor>
{
//Sameas<Logging_Acceptor>...
};
VanderbiltUniversity
AdvancedACETutorialDo
Thr_Logging_Handler
Implementation
OverridedefinitionintheACE_Svc_Handlerclass
tospawnanewthread
int
Thr_Logging_Handler::open(void*)
{
//Spawnanewthreadtohandle
//loggingrecordswiththeclient.
activate(THR_DETACHED);
}
Processremoteloggingrecordsbyloopinguntil
clientterminatesconnection
int
Thr_Logging_Handler::svc(void)
{
while(handle_input()!=-1)
//Callexistingfunctiontorecv
//loggingrecordandprinttostdout.
continue;
}
VanderbiltUniversity
AdvancedACETutorialDouglasC.Schmidt
DynamicallyReconfiguringtheLoggingServer
Theloggingserviceis
configuredviascriptingina
svc.conffile:
%cat./svc.conf
#Dynamicallyreconfigure
#theloggingservice
removeLogger
dynamicLogger
Service_Object*
thr_logger:_make_Logger()
"-p2002"
#.dllor.sosuffixaddedto
#"thr_logger"automatically
Dynamicallylinkedfactory
functionthatallocatesanew
threadedLogging_Acceptor
extern"C"
ACE_Service_Object*make_Logger(void);
ACE_Service_Object*
make_Logger(void)
{
returnnewThr_Logging_Acceptor;
}
Loggingserviceisreconfiguredbychangingthesvc.conffileand
sendingSIGHUPsignaltoserver
VanderbiltUniversity
137
AdvancedACETutorialDouglasC.Schmidt
CaveatsfortheConcurrentLoggingServer
￿
TheconcurrentLoggingServerhasseveralproblems
–Outputinthehandle_log_record()functionisnotserialized
–Theauto-incrementofglobalvariablerequest_countisalso
notserialized
￿
Lackofserializationleadstoerrorsonmanysharedmemory
multi-processorplatforms...
–Notethatthisproblemisindicativeofalargeclassoferrorsin
concurrentprograms...
￿
Thefollowingslidescompareandcontrastaseriesoftechniques