%!PS-Adobe-2.0 %%Creator: dvips, version 5.396 (C) 1986-90 Radical Eye Software %%Title: fourth.dvi %%Pages: 15 1 %%BoundingBox: 0 0 612 792 %%DocumentFonts: Times-Bold Times-Roman Times-Italic Courier %%EndComments %%BeginProcSet: tex.pro /TeXDict 200 dict def TeXDict begin /N /def load def /B{bind def}N /S /exch load def /X{S N}B /TR /translate load N /isls false N /vsize 10 N /@rigin{ isls{[0 1 -1 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale Resolution VResolution vsize neg mul TR}B /@letter{/vsize 10 N}B /@landscape{ /isls true N /vsize -1 N}B /@a4{/vsize 10.6929133858 N}B /@legal{/vsize 13 N} B /@manualfeed{statusdict /manualfeed true put}B /@copies{/#copies X}B /FMat[ 1 0 0 -1 0 0]N /FBB[0 0 0 0]N /df{/sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0 0 sf neg 0 0]N df-tail}B /df-tail{/nn 8 dict N nn begin /FontType 3 N /FontMatrix fntrx N /FontBBox FBB N string /base X array /BitMaps X /BuildChar{CharBuilder}N /Encoding IE N end dup{/foo setfont}2 array copy cvx N load 0 nn put /ctr 0 N[}B /E{pop nn dup definefont setfont}B /ch-image{ch-data dup type /stringtype ne{ctr get /ctr ctr 1 add N}if}B /ch-width{ch-data dup length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{128 ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub get 127 sub}B /ch-dx{ch-data dup length 1 sub get}B /ctr 0 N /CharBuilder{save 3 1 roll S dup /base get 2 index get S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx 0 ch-xoff ch-yoff ch-height sub ch-xoff ch-width add ch-yoff setcachedevice ch-width ch-height true[1 0 0 -1 -.1 ch-xoff sub ch-yoff .1 add]{ch-image}imagemask restore}B /D{/cc X dup type /stringtype ne{ ]}if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{dup dup length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N}B /I{cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin 0 0 moveto}B /eop{ clear SI restore showpage userdict /eop-hook known{eop-hook}if}B /@start{ userdict /start-hook known{start-hook}if /VResolution X /Resolution X 1000 div /DVImag X /IE 256 array N 0 1 255{IE S 1 string dup 0 3 index put cvn put}for} B /p /show load N /RMat[1 0 0 -1 0 0]N /BDot 8 string N /v{/ruley X /rulex X V }B /V{gsave TR -.1 -.1 TR rulex ruley scale 1 1 false RMat{BDot}imagemask grestore}B /a{moveto}B /delta 0 N /tail{dup /delta X 0 rmoveto}B /M{S p delta add tail}B /b{S p tail}B /c{-4 M}B /d{-3 M}B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{ 1 M}B /i{2 M}B /j{3 M}B /k{4 M}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w }B /q{p 1 w}B /r{p 2 w}B /s{p 3 w}B /t{p 4 w}B /w{0 rmoveto}B /x{0 S rmoveto} B /y{3 2 roll p a}B /bos{/SS save N}B /eos{clear SS restore}B end %%EndProcSet %%BeginProcSet: texps.pro TeXDict begin /rf{655360 div mul Resolution mul 7227 div /PixPerEm X findfont dup length 1 add dict /nn X{1 index /FID ne{nn 3 1 roll put}{pop pop}ifelse} forall 256 dict begin nn /Encoding get 0 1 255{2 copy get 3 index 2 index get 1000 mul PixPerEm div N pop}for pop pop nn /Metrics currentdict put end /fontname X /nn dup nn definefont[PixPerEm 0 0 PixPerEm neg 0 0]makefont N fontname{/foo setfont}2 array copy cvx N fontname load 0 nn put}B /ObliqueSlant{dup sin S cos div neg}B /SlantFont{/foo X[1 0 foo 1 0 0] TransFont}B /ExtendFont{/foo X 3 2 roll[S{foo div}forall]3 1 roll[foo 0 0 1 0 0]TransFont}B /TransFont{S findfont S makefont dup length dict /nn X{1 index /FID ne{nn 3 1 roll put}{pop pop}ifelse}forall dup nn definefont pop}B end %%EndProcSet %%BeginProcSet: special.pro TeXDict begin /SDict 200 dict N SDict begin /@SpecialDefaults{/hs 612 N /vs 792 N /ho 0 N /vo 0 N /hsc 1 N /vsc 1 N /ang 0 N /CLIP false N /BBcalc false N }B /@scaleunit 100 N /@hscale{@scaleunit div /hsc X}B /@vscale{@scaleunit div /vsc X}B /@hsize{/hs X /CLIP true N}B /@vsize{/vs X /CLIP true N}B /@hoffset{ /ho X}B /@voffset{/vo X}B /@angle{/ang X}B /@rwi{10 div /rwi X}B /@llx{/llx X} B /@lly{/lly X}B /@urx{/urx X}B /@ury{/ury X /BBcalc true N}B /magscale true def end /@MacSetUp{userdict /md known{userdict /md get type /dicttype eq{md begin /letter{}N /note{}N /legal{}N /od{txpose 1 0 mtx defaultmatrix dtransform S atan/pa X newpath clippath mark{transform{itransform moveto}}{ transform{itransform lineto}}{6 -2 roll transform 6 -2 roll transform 6 -2 roll transform{itransform 6 2 roll itransform 6 2 roll itransform 6 2 roll curveto}}{{closepath}}pathforall newpath counttomark array astore /gc xdf pop ct 39 0 put 10 fz 0 fs 2 F/|______Courier fnt invertflag{PaintBlack}if}N /txpose{pxs pys scale ppr aload pop por{noflips{pop S neg S TR pop 1 -1 scale} if xflip yflip and{pop S neg S TR 180 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip yflip not and{pop S neg S TR pop 180 rotate ppr 3 get ppr 1 get neg sub neg 0 TR}if yflip xflip not and{ppr 1 get neg ppr 0 get neg TR}if}{noflips{TR pop pop 270 rotate 1 -1 scale}if xflip yflip and{TR pop pop 90 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip yflip not and{TR pop pop 90 rotate ppr 3 get ppr 1 get neg sub neg 0 TR}if yflip xflip not and{TR pop pop 270 rotate ppr 2 get ppr 0 get neg sub neg 0 S TR}if}ifelse scaleby96{ ppr aload pop 4 -1 roll add 2 div 3 1 roll add 2 div 2 copy TR .96 dup scale neg S neg S TR}if}N /cp{pop pop showpage pm restore}N end}if}if}N /normalscale {Resolution 72 div VResolution 72 div neg scale magscale{DVImag dup scale}if} N /psfts{S 65536 div N}N /startTexFig{/psf$SavedState save N userdict maxlength dict begin /magscale false def normalscale currentpoint TR /psf$ury psfts /psf$urx psfts /psf$lly psfts /psf$llx psfts /psf$y psfts /psf$x psfts currentpoint /psf$cy X /psf$cx X /psf$sx psf$x psf$urx psf$llx sub div N /psf$sy psf$y psf$ury psf$lly sub div N psf$sx psf$sy scale psf$cx psf$sx div psf$llx sub psf$cy psf$sy div psf$ury sub TR /showpage{}N /erasepage{}N /copypage{}N @MacSetUp}N /doclip{psf$llx psf$lly psf$urx psf$ury currentpoint 6 2 roll newpath 4 copy 4 2 roll moveto 6 -1 roll S lineto S lineto S lineto closepath clip newpath moveto}N /endTexFig{end psf$SavedState restore}N /@beginspecial{SDict begin /SpecialSave save N gsave normalscale currentpoint TR @SpecialDefaults}B /@setspecial{CLIP{newpath 0 0 moveto hs 0 rlineto 0 vs rlineto hs neg 0 rlineto closepath clip}{initclip}ifelse ho vo TR hsc vsc scale ang rotate BBcalc{rwi urx llx sub div dup scale llx neg lly neg TR}if /showpage{}N /erasepage{}N /copypage{}N newpath}B /@endspecial{grestore clear SpecialSave restore end}B /@defspecial{SDict begin}B /@fedspecial{end}B /li{ lineto}B /rl{rlineto}B /rc{rcurveto}B /np{/SaveX currentpoint /SaveY X N 1 setlinecap newpath}B /st{stroke SaveX SaveY moveto}B /fil{fill SaveX SaveY moveto}B /ellipse{/endangle X /startangle X /yrad X /xrad X /savematrix matrix currentmatrix N TR xrad yrad scale 0 0 1 startangle endangle arc savematrix setmatrix}B end %%EndProcSet TeXDict begin 1000 300 300 @start /Fa [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 10 14 17 21 21 35 32 14 14 14 21 23 10 14 10 12 21 21 21 21 21 21 21 21 21 21 12 12 23 23 23 18 38 30 28 28 30 25 23 30 30 14 16 30 25 37 30 30 23 30 28 23 25 30 30 39 30 30 25 14 12 14 19 21 14 18 21 18 21 18 14 21 21 12 12 21 12 32 21 21 21 21 14 16 12 21 21 30 21 21 18 20 8 20 22 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 14 21 21 7 21 21 21 21 7 18 21 14 14 23 23 0 21 21 21 10 0 19 15 14 18 18 21 42 42 0 18 0 14 14 14 14 14 14 14 14 0 14 14 0 14 14 14 42 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 37 0 11 0 0 0 0 25 30 37 13 0 0 0 0 0 28 0 0 0 12 0 0 12 21 30 21 0 0 0 0 ] /Times-Roman 1000 655360 rf /Fb 1 23 df<01801801C01C03803803803803803803803807007007007007007007 00700E00E00E00E00E00E00E00E11E01C21E01C21E03C21E05C43F08C439F07838000038000070 0000700000700000700000E00000E00000E00000C00000181E7F931B>22 D E /Fc [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 11 15 19 23 23 38 35 15 15 15 23 31 11 15 11 13 23 23 23 23 23 23 23 23 23 23 15 15 31 31 31 23 42 28 28 30 33 28 28 33 33 15 20 30 25 38 30 33 28 33 28 23 25 33 28 38 28 25 25 18 13 18 19 23 15 23 23 20 23 20 13 23 23 13 13 20 13 33 23 23 23 23 18 18 13 23 20 30 20 20 18 18 12 18 25 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 18 23 23 8 23 23 23 23 10 25 23 15 15 23 23 0 23 23 23 11 0 24 16 15 25 25 23 40 45 0 23 0 15 15 15 15 15 15 15 15 0 15 15 0 15 15 15 40 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 40 0 13 0 0 0 0 25 33 43 14 0 0 0 0 0 30 0 0 0 13 0 0 13 23 30 23 0 0 0 0 ] /Times-Italic 1000 717619 rf /Fd [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 25 25 25 25 25 25 25 25 25 25 25 25 25 0 0 0 25 25 25 25 0 25 25 25 25 25 25 25 0 0 25 0 25 25 25 25 25 25 25 25 0 25 25 0 25 25 25 25 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 25 0 0 0 0 25 25 0 25 0 0 0 0 0 0 0 0 0 25 0 0 25 25 0 25 0 0 0 0 ] /Courier 1000 655360 rf /Fe [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 27 27 27 27 27 27 27 27 27 27 27 27 27 0 0 0 27 27 27 27 0 27 27 27 27 27 27 27 0 0 27 0 27 27 27 27 27 27 27 27 0 27 27 0 27 27 27 27 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 27 0 0 0 0 27 27 0 27 0 0 0 0 0 0 0 0 0 27 0 0 27 27 0 27 0 0 0 0 ] /Courier 1000 717619 rf /Ff [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 17 28 25 25 50 41 17 17 17 25 28 12 17 12 14 25 25 25 25 25 25 25 25 25 25 17 17 28 28 28 25 46 36 33 36 36 33 30 39 39 19 25 39 33 47 36 39 30 39 36 28 33 36 36 50 36 36 33 17 14 17 29 25 17 25 28 22 28 22 17 25 28 14 17 28 14 41 28 25 28 28 22 19 17 28 25 36 25 25 22 20 11 20 26 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 17 25 25 8 25 25 25 25 14 25 25 17 17 28 28 0 25 25 25 12 0 27 17 17 25 25 25 50 50 0 25 0 17 17 17 17 17 17 17 17 0 17 17 0 17 17 17 50 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 50 0 15 0 0 0 0 33 39 50 16 0 0 0 0 0 36 0 0 0 14 0 0 14 25 36 28 0 0 0 0 ] /Times-Bold 1000 786432 rf /Fg [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 9 12 15 19 19 31 29 12 12 12 19 21 9 12 9 10 19 19 19 19 19 19 19 19 19 19 10 10 21 21 21 17 34 27 25 25 27 23 21 27 27 12 15 27 23 33 27 27 21 27 25 21 23 27 27 35 27 27 23 12 10 12 18 19 12 17 19 17 19 17 12 19 19 10 10 19 10 29 19 19 19 19 12 15 10 19 19 27 19 19 17 18 7 18 20 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 19 19 6 19 19 19 19 7 17 19 12 12 21 21 0 19 19 19 9 0 17 13 12 17 17 19 37 37 0 17 0 12 12 12 12 12 12 12 12 0 12 12 0 12 12 12 37 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 33 0 10 0 0 0 0 23 27 33 12 0 0 0 0 0 25 0 0 0 10 0 0 10 19 27 19 0 0 0 0 ] /Times-Roman 1000 589824 rf /Fh 1 4 df<0C000C008C40EDC07F800C 007F80EDC08C400C000C000A0B7D8B10>3 D E /Fi [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 11 15 19 23 23 38 35 15 15 15 23 26 11 15 11 13 23 23 23 23 23 23 23 23 23 23 13 13 26 26 26 20 42 33 30 30 33 28 25 33 33 15 18 33 28 40 33 33 25 33 30 25 28 33 33 43 33 33 28 15 13 15 21 23 15 20 23 20 23 20 15 23 23 13 13 23 13 35 23 23 23 23 15 18 13 23 23 33 23 23 20 22 9 22 25 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 15 23 23 8 23 23 23 23 8 20 23 15 15 25 25 0 23 23 23 11 0 21 16 15 20 20 23 45 45 0 20 0 15 15 15 15 15 15 15 15 0 15 15 0 15 15 15 45 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 40 0 13 0 0 0 0 28 33 40 14 0 0 0 0 0 30 0 0 0 13 0 0 13 23 33 23 0 0 0 0 ] /Times-Roman 1000 717619 rf /Fj [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 15 20 33 30 30 60 50 20 20 20 30 34 15 20 15 17 30 30 30 30 30 30 30 30 30 30 20 20 34 34 34 30 56 43 40 43 43 40 37 47 47 23 30 47 40 56 43 47 37 47 43 33 40 43 43 60 43 43 40 20 17 20 35 30 20 30 33 27 33 27 20 30 33 17 20 33 17 50 33 30 33 33 27 23 20 33 30 43 30 30 27 24 13 24 31 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 20 30 30 10 30 30 30 30 17 30 30 20 20 33 33 0 30 30 30 15 0 32 21 20 30 30 30 60 60 0 30 0 20 20 20 20 20 20 20 20 0 20 20 0 20 20 20 60 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 60 0 18 0 0 0 0 40 47 60 20 0 0 0 0 0 43 0 0 0 17 0 0 17 30 43 33 0 0 0 0 ] /Times-Bold 1000 943718 rf /Fk [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 10 14 17 21 21 35 32 14 14 14 21 28 10 14 10 12 21 21 21 21 21 21 21 21 21 21 14 14 28 28 28 21 38 25 25 28 30 25 25 30 30 14 18 28 23 35 28 30 25 30 25 21 23 30 25 35 25 23 23 16 12 16 18 21 14 21 21 18 21 18 12 21 21 12 12 18 12 30 21 21 21 21 16 16 12 21 18 28 18 18 16 17 11 17 22 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 16 21 21 7 21 21 21 21 9 23 21 14 14 21 21 0 21 21 21 10 0 22 15 14 23 23 21 37 42 0 21 0 14 14 14 14 14 14 14 14 0 14 14 0 14 14 14 37 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 37 0 11 0 0 0 0 23 30 39 13 0 0 0 0 0 28 0 0 0 12 0 0 12 21 28 21 0 0 0 0 ] /Times-Italic 1000 655360 rf /Fl [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 10 14 23 21 21 42 35 14 14 14 21 24 10 14 10 12 21 21 21 21 21 21 21 21 21 21 14 14 24 24 24 21 39 30 28 30 30 28 25 32 32 16 21 32 28 39 30 32 25 32 30 23 28 30 30 42 30 30 28 14 12 14 24 21 14 21 23 18 23 18 14 21 23 12 14 23 12 35 23 21 23 23 18 16 14 23 21 30 21 21 18 16 9 16 22 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 14 21 21 7 21 21 21 21 12 21 21 14 14 23 23 0 21 21 21 10 0 22 15 14 21 21 21 42 42 0 21 0 14 14 14 14 14 14 14 14 0 14 14 0 14 14 14 42 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 42 0 12 0 0 0 0 28 32 42 14 0 0 0 0 0 30 0 0 0 12 0 0 12 21 30 23 0 0 0 0 ] /Times-Bold 1000 655360 rf /Fm 1 4 df<020002000200C218F2783AE00F800F803AE0F278C218020002000200 0D0E7E8E12>3 D E /Fn [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 17 20 25 25 41 39 17 17 17 25 28 12 17 12 14 25 25 25 25 25 25 25 25 25 25 14 14 28 28 28 22 46 36 33 33 36 30 28 36 36 17 19 36 30 44 36 36 28 36 33 28 30 36 36 47 36 36 30 17 14 17 23 25 17 22 25 22 25 22 17 25 25 14 14 25 14 39 25 25 25 25 17 19 14 25 25 36 25 25 22 24 10 24 27 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 17 25 25 8 25 25 25 25 9 22 25 17 17 28 28 0 25 25 25 12 0 23 17 17 22 22 25 50 50 0 22 0 17 17 17 17 17 17 17 17 0 17 17 0 17 17 17 50 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 44 0 14 0 0 0 0 30 36 44 15 0 0 0 0 0 33 0 0 0 14 0 0 14 25 36 25 0 0 0 0 ] /Times-Roman 1000 786432 rf /Fo [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 18 24 40 36 36 72 60 24 24 24 36 41 18 24 18 20 36 36 36 36 36 36 36 36 36 36 24 24 41 41 41 36 67 52 48 52 52 48 44 56 56 28 36 56 48 68 52 56 44 56 52 40 48 52 52 72 52 52 48 24 20 24 42 36 24 36 40 32 40 32 24 36 40 20 24 40 20 60 40 36 40 40 32 28 24 40 36 52 36 36 32 28 16 28 37 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 24 36 36 12 36 36 36 36 20 36 36 24 24 40 40 0 36 36 36 18 0 39 25 24 36 36 36 72 72 0 36 0 24 24 24 24 24 24 24 24 0 24 24 0 24 24 24 72 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 72 0 22 0 0 0 0 48 56 72 24 0 0 0 0 0 52 0 0 0 20 0 0 20 36 52 40 0 0 0 0 ] /Times-Bold 1000 1132462 rf end %%EndProlog %%BeginSetup %%Feature: *Resolution 300 TeXDict begin @letter %%EndSetup %%Page: 1 1 bop 293 224 a Fo(W)o(riting)17 b(a)h(Client-Server)e(Application)h(in)g(C++) 337 350 y Fn(Paulo)12 b(Guedes)612 332 y Fm(\003)1276 350 y Fn(Daniel)g(Julin)244 466 y(OSF)g(Research)h(Institute)405 b(School)11 b(of)h(Computer)g(Science)273 524 y(1)g(Cambridge)g(Center)441 b(Carnegie)12 b(Mellon)g(University)237 583 y(Cambridge,)g(MA)25 b(02142)466 b(Pittsbur)o(gh,)11 b(P)-5 b(A)25 b(15213)351 641 y(pjg@osf.or)o(g)630 b(dpj@cs.cmu.edu)883 836 y Fl(Abstract)251 904 y Fk(Applications)5 b(based)h(on)h(the)g(client-server)g(model)g(place)f (a)h(special)g(emphasis)f(on)h(the)f(specification)189 954 y(of)k(interfaces,)h(the)g(separation)e(of)h(interface)h(and)f (implementation)e(and)i(on)h(the)f(support)g(for)g(multiple)189 1004 y(implementations)f(of)i(the)g(same)h(interface.)j(The)d(class)g (hierarchy)g(of)f(such)h(an)f(application)e(has)i(to)g(be)189 1054 y(designed)f(while)f(taking)g(these)i(issues)f(into)f(account.)251 1103 y(In)14 b(this)g(paper)g(we)h(present)g(a)f(model)h(for)f(writing)e (client-server)k(applications)c(in)i(C++,)i(based)189 1153 y(in)h(our)g(experience)j(with)c(the)h(Mach)g(3)h(multi-server)g(system.)33 b(Interfaces)18 b(are)g(defined)f(by)h(C++)189 1203 y(abstract)c(classes,)j (from)e(which)f(implementations)f(are)i(derived.)26 b(Implementations)13 b(generally)i(use)189 1253 y(multiple-inherit)o(ance)8 b(to)i(inherit)f (functionalit)o(y)f(from)i(other)g(implementation)d(classes.)251 1303 y(We)15 b(describe)h(how)f(this)f(simple)h(model)f(was)h(applied)f(to)h (the)g(construction)f(of)g(the)h(clients)g(and)189 1352 y(servers)21 b(that)e(compose)h(the)g(Mach)f(3)h(multi-server,)i(using)d(standard)f(C++.) 39 b(We)20 b(discuss)g(how)189 1402 y(multiple-inherit)o(ance)10 b(simplified)f(the)j(design)f(of)h(the)f(system)i(and)e(the)h(need)g(for)g (run-time,)g(type-safe)189 1452 y(pointer)g(conversion.)21 b(Finally,)14 b(we)f(give)h(an)f(overview)i(of)e(our)g(class)h(library)f(and) f(relevant)i(aspects)189 1502 y(of)e(the)h(remote)h(object)e(invocation)g (subsystem)h(and)g(summarize)g(our)g(experience)i(with)d(C++)h(in)f(this)189 1552 y(project.)75 1696 y Fj(1)60 b(Intr)o(oduction)75 1799 y Fi(A)14 b(major)f(aspect)h(of)g(a)g(system)f(composed)g(of)g(cooperating)g (clients)f(and)i(servers)f(is)g(how)h(the)f(interactions)75 1856 y(between)e(them)g(are)h(speci\256ed)f(and)g(implemented.)125 1912 y(T)n(raditionally)m(,)f(the)i(interface)g(to)g(a)g(server)g(is)f (composed)h(of)g(a)g(set)g(of)g(routines)e(and)i(is)f(speci\256ed)h(with)f (an)75 1969 y(Interface)e(De\256nition)e(Language)h(\(IDL\).)h(A)g(compiler)n (,)g(called)f(the)g(stub)g(generator)n(,)h(generates)f(the)h(stubs)e(that)75 2025 y(are)12 b(linked)e(to)h(the)f(clients,)h(isolating)e(their)i(code)g (from)g(the)g(details)f(of)i(the)f(communication)f(mechanisms.)125 2082 y(In)15 b(an)g(object-oriented)e(environment)h(the)h(natural)g (evolution)e(is)h(to)h(encapsulate)f(the)h(interface)g(to)f(the)75 2138 y(server)g(in)e(one)i(or)f(more)h(classes,)g(de\256ne)f(their)g (interface)h(in)f(a)g(language-independent)e(way)i(with)g(an)g(IDL)75 2195 y(and)e(generate)f(stub)g(classes)g(to)g(link)g(with)g(clients)f(and)i (servers.)16 b(Several)11 b(projects)f(have)h(implemented)f(stub)75 2251 y(generators)h(for)g(C++[4)o(,)h(11].)125 2308 y(However)n(,)c(there)g (are)g(a)g(number)g(of)f(limitations)e(with)i(this)f(simple)h(approach.)15 b(One)8 b(of)f(the)h(major)f(concerns)75 2364 y(of)15 b(a)g(designer)g(of)g (a)g(distributed)d(application)i(is)g(the)h(optimization)e(of)i(the)f (interactions)g(between)g(clients)75 2420 y(and)h(servers,)h(as)f(they)g (amount)f(to)h(a)g(very)g(signi\256cant)f(percentage)h(of)g(the)g(costs)f (involved.)27 b(A)15 b(common)75 2477 y(technique)8 b(to)h(deal)h(with)e (this)g(problem)i(is)f(to)g(use)g(proxy)f(objects[13)o(].)16 b(Such)10 b(objects)e(are)i(stubs)e(with)h(special)75 2533 y(hooks)i(to)i(allow)e(the)i(programmer)g(to)f(optimize)g(or)h(even)g(avoid)e (the)i(communication)e(between)i(the)f(client)75 2590 y(and)f(the)g(server)g (while)g(keeping)f(the)h(structure)f(of)h(the)g(application)f(clean.)p 75 2627 708 2 v 124 2654 a Fh(\003)142 2670 y Fg(Author)q(')n(s)g(current)f (address:)j(INESC/IST)m(,)e(R.)g(Alves)e(Redol)h(9,)g(1000)f(Lisboa,)h (Portugal)f(\(pjg@sabrina.inesc.pt\))p eop %%Page: 2 2 bop 125 42 a Fi(Multiple)7 b(implementations)f(of)i(the)g(same)g(interface)g (are)h(the)f(rule)g(and)f(not)h(the)f(exception)g(in)h(client-server)75 98 y(applications.)14 b(There)d(are)h(at)e(least)g(always)g(two)h (implementations)d(for)j(each)g(interface,)h(the)e(client-side)f(and)75 154 y(the)j(server)o(-side)g(implementation,)f(but)g(often)h(systems)f(need)h (a)g(number)g(of)g(dif)o(ferent)g(implementations)f(to)75 211 y(handle)g(various)f(communication)g(mechanisms.)125 267 y(Another)j(concern) i(is)f(the)g(extensibility)d(of)k(the)f(system)g(to)g(allow)f(a)i(newer)g (version)e(of)i(a)f(server)h(to)f(be)75 324 y(able)c(to)g(work)g(with)g (existing)e(clients,)i(and)g(conversely)g(to)g(allow)f(clients)h(to)g(work)g (with)f(old)h(versions)f(of)h(the)75 380 y(servers.)19 b(Subtyping)11 b(of)h(object-oriented)e(languages)h(is)h(a)g(major)h(tool)e(to)h(handle)f (this)g(problem,)h(but)g(it)f(has)75 437 y(to)g(be)h(used)f(carefully)g(and)h (ef)o(fectively)m(.)18 b(Moreover)n(,)12 b(the)g(precise)f(subtyping)e(rules) j(of)f(the)h(implementation)75 493 y(language)e(do)h(not)g(usually)e(match)j (those)e(of)h(the)g(IDL.)125 550 y(In)h(this)f(paper)h(we)g(describe)f(how)h (we)g(approach)f(these)h(issues)f(in)g(the)h(Mach)g(3)g(multi-server)f (system[5)o(].)75 606 y(This)d(system)g(is)h(composed)f(of)h(a)h(number)f(of) g(servers)g(running)e(on)i(top)f(of)h(the)g(Mach)h(3)e(kernel,)i(together)e (with)75 663 y(emulation)13 b(libraries)g(executing)g(in)g(the)h(address)f (space)h(of)g(the)g(user)g(programs.)25 b(T)m(ogether)n(,)14 b(they)f(provide)75 719 y(the)i(complete)g(services)g(of)h(an)f(operating)f (system.)29 b(Both)15 b(the)g(servers)g(and)h(the)f(emulation)f(libraries)g (are)75 775 y(programmed)8 b(as)g(a)f(set)h(of)f(C++)g(objects)g(that)g (communicate)g(by)g(invocation)f(of)i(C++)f(functions,)g(independent)75 832 y(of)h(their)f(location.)14 b(Clients)7 b(and)g(servers)h(are)g (constructed)e(from)j(a)f(library)f(containing)e(a)j(number)g(of)g(common)75 888 y(C++)h(classes.)16 b(Both)9 b(the)g(interfaces)g(and)g(their)g (implementation)f(are)i(speci\256ed)g(in)f(C++.)15 b(Several)10 b(interfaces)75 945 y(have)h(multiple)f(client)g(and)h(server)o(-side)g (implementations.)j(Servers)e(may)f(be)g(modi\256ed)g(without)e(requiring)75 1001 y(changes)i(to)f(existing)g(clients.)75 1146 y Fj(2)60 b(Interface)13 b(and)i(Implementation)75 1249 y Fi(This)h(section)f (describes)h(how)g(we)h(specify)f(the)g(interfaces)h(between)f(clients)g(and) g(servers)h(and)f(how)g(we)75 1306 y(support)10 b(dif)o(ferent)h(client-side) e(and)i(server)o(-side)g(implementations.)75 1429 y Ff(2.1)50 b(Interface)75 1516 y Fi(The)12 b(interfaces)g(between)f(clients)g(and)h (servers)g(are)h(de\256ned)f(with)f(C++)h(abstract)f(classes.)19 b(For)12 b(the)g(sake)g(of)75 1573 y(clarity)h(we)h(shall)f(ignore)g(for)h (the)f(moment)h(the)f(details)g(of)h(the)f(RPC)i(subsystem)d(and)i (concentrate)f(on)g(the)75 1629 y(programmer)r(')m(s)f(view)e(of)h(the)g(C++) g(class)f(hierarchy)m(.)17 b(When)11 b(writing)e(a)i(server)n(,)h(the)f (programmer)h(must)e(\256rst)75 1685 y(design)j(the)h(classes)g(that)g(are)h (externally)f(visible)e(by)i(clients)g(and)g(then)g(de\256ne)g(the)h(C++)f (abstract)g(classes)75 1742 y(that)d(constitute)e(the)j(interface.)17 b(These)11 b(abstract)g(classes)g(are)i(the)e(only)f(server)i(classes)f(seen) g(by)g(the)h(client')m(s)75 1798 y(code.)17 b(For)11 b(example,)h(if)f(the)g (server)g(de\256nes)g(classes)g Fe(naming)i Fi(and)e Fe(file)h Fi(as:)75 1890 y Fd(class)24 b(file)h({)224 1940 y(public:)274 1990 y(virtual)g(int)f(read\(char*,)g(int\))h(=0;)274 2040 y(virtual)g(int)f(write\(char*,)g(int\))g(=0;)75 2089 y(};)75 2181 y(class)g(naming)h({)224 2231 y(public:)274 2281 y(virtual)g(int)f (open\(char*,)g(file**\))g(=0;)75 2330 y(};)75 2429 y Fi(a)12 b(client)e(would)g(use)h(them)g(as)g(follows:)274 2521 y Fd(file*)25 b(f;)274 2570 y(char)50 b(buf[1024];)274 2620 y(int)25 b(error)f(=)h (fileserver->open\("myfile",)e(&f\);)274 2670 y(int)i(bytesread)f(=)h (f->read\(buf,)f(1024\);)p eop %%Page: 3 3 bop 75 42 a Fi(\(assuming)14 b(for)h(the)f(moment)h(that)f(variable)g Fe(fileserver)k Fi(is)c(of)g(type)g Fe(naming)j Fi(and)d(has)h(been)f(previ-) 75 98 y(ously)e(initialized\).)21 b(The)13 b(important)f(thing)g(to)h(note)g (is)f(that)h(this)f(code)h(is)g(completely)g(independent)e(of)i(the)75 154 y(implementation)e(of)i(classes)g Fe(naming)42 b Fi(or)13 b Fe(file)p Fi(,)i(of)e(the)f(mechanism)i(used)e(to)g(communicate)i(with)d (the)75 211 y(server)i(and)f(even)h(of)g(the)f(location)f(of)i(the)g Fe(naming)h Fi(and)e Fe(file)i Fi(instances.)20 b(The)13 b(designer)f(of)g (the)h(system)75 267 y(has)e(complete)g(freedom)h(to)f(choose)g(the)g (location)e(of)j(the)f(various)f(objects)g(and)h(to)g(use)g(the)g (communication)75 324 y(mechanisms)i(most)f(appropriate)g(to)g(any)h(given)f (con\256guration.)20 b(In)13 b(particular)n(,)g(if)f(the)h(object)f(being)g (refer)o(-)75 380 y(enced)e(happens)g(to)f(be)i(co-located)e(with)g(the)h (client,)g(it)g(is)g(accessed)g(directly)f(as)h(in)g(a)h(normal)f(C++)g (program.)75 437 y(The)16 b(system)f(can)i(be)f(conceived)f(in)h(terms)g(of)g (classes,)h(or)f(services,)h(instead)e(of)h(being)f(decomposed)h(in)75 493 y(address)10 b(spaces)h(and)g(servers.)16 b(That)10 b(decomposition)f (may)i(be)g(postponed)e(to)h(a)h(latter)g(phase,)g(when)f(servers)75 550 y(are)i(assembled)f(out)g(of)h(the)f(library)g(of)h(classes)f(in)g(the)g (con\256guration)f(that)h(better)g(\256ts)h(the)f(hardware)h(or)f(any)75 606 y(other)g(external)g(constraints)e(\(e.g.)17 b(security)m(,)11 b(performance\).)75 730 y Ff(2.2)50 b(Implementation)75 817 y Fi(A)18 b(client-side)e(implementation)g(class)h(or)h(proxy)f(is)g(always)g (a)h(subclass)f(of)g(the)h(interface)f(class)h(that)f(it)75 874 y(implements.)24 b(In)14 b(the)f Fe(file)j Fi(example,)f(a)f(simple)f (implementation)g(that)g(sends)g(a)h(RPC)h(to)e(the)h(server)g(for)75 930 y(each)e(request)e(would)g(be)i(as)f(follows:)75 1030 y Fd(class)24 b(rpc)h({)274 1080 y(mach_port_t)f(server_port;)224 1130 y(public:)274 1179 y(virtual)h(do_rpc\(int)e(method_id,)h(...\))h({)g (/*)g(some)f(implementation)g(*/)g(})75 1229 y(};)75 1329 y(class)g (client_rpc_file:)g(public)g(virtual)g(file,)h(public)f(virtual)g(rpc)h({)224 1379 y(public:)274 1428 y(virtual)g(int)f(read\(char*)g(buf,)h(int)f(len\))h ({)474 1478 y(return)f(do_rpc\(method_id\(read\),)f(buf,)h(len\);)274 1528 y(})274 1578 y(virtual)h(int)f(write\(char*)g(buf,)h(int)f(len\))h({)474 1628 y(return)f(do_rpc\(method_id\(write\),)f(buf,)h(len\);)274 1677 y(})75 1727 y(};)75 1834 y Fi(where)8 b(class)f Fe(rpc)i Fi(is)e(a)i(generic)e(class)h(that)f(implements)g(remote)h(procedure)g(calls) f(and)h(uses)f Fe(server)p 1721 1834 14 2 v 18 w(port)75 1890 y Fi(as)k(the)g(communication)f(handle)h(to)g(talk)f(to)h(the)g(server)m(.) 125 1946 y(When)e(the)f Fe(open)j Fi(function)d(is)g(called,)i(the)f(RPC)h (subsystem)d(creates)j(an)f(instance)f(of)h(an)h(implementation)75 2003 y(class,)19 b Fe(client)p 359 2003 V 18 w(rpc)p 458 2003 V 17 w(file)g Fi(in)e(this)f(case,)k(and)d(returns)g(it)g(to)g(the)g(client.) 35 b(This)17 b(is)f(possible)g(because)75 2059 y Fe(client)p 240 2059 V 18 w(rpc)p 339 2059 V 17 w(file)h Fi(is)e(a)i(subclass)d(of)i Fe(client)h Fi(and)f(therefore)g(can)g(be)g(used)f(wherever)h(a)g Fe(client)75 2116 y Fi(is)h(expected.)37 b(Class)17 b Fe(client)p 614 2116 V 18 w(rpc)p 713 2116 V 18 w(file)i Fi(also)e(uses)h(inheritance)f (to)g(reuse)h(the)g(implementation)e(of)75 2172 y(class)e Fe(rpc)p Fi(.)28 b(Inheritance)14 b(is)g(used)g(here)h(with)f(two)g(of)g(the)g(three)h (meanings)f(described)g(by[15)o(],)i(interface)75 2229 y(inheritance)10 b(and)h(implementation)f(inheritance.)125 2285 y(If)j(there)g(are)h(multiple) e(implementations)f(of)j(the)e(same)i(interface,)g(the)f(RPC)h(subsystem)e (has)h(to)f(decide)75 2342 y(which)g(one)h(to)g(instantiate.)20 b(In)13 b(our)g(system)f(this)g(is)h(determined)g(by)f(the)h(server)n(,)h(by) f(sending)f(the)g(name)i(of)75 2398 y(the)d(client-side)f(implementation)f (that)i(should)e(be)j(created.)125 2455 y(Server)o(-side)h(implementations)f (follow)g(the)h(same)h(pattern:)20 b(each)13 b(implementation)f(class)h(is)g (a)h(subtype)75 2511 y(of)9 b(the)g(interface)h(that)e(it)h(implements)g(and) g(also)g(inherits)e(code)j(from)g(the)f(implementation)e(class)i(of)h(the)f (level)75 2567 y(above.)p eop %%Page: 4 4 bop 75 42 a Ff(2.3)50 b(Why)12 b(Multiple-Inheritance)75 129 y Fi(The)i(advantage)f(of)i(using)d(multiple-inheritance)g(becomes)j (apparent)e(when)h(we)g(consider)f Fc(extending)g Fi(the)75 185 y(system)e(by)f(deriving)g(new)h(interfaces)g(from)h(the)f(existing)e (ones.)125 241 y(Consider)n(,)16 b(for)f(example,)i(that)e(we)g(de\256ne)h(a) f(new)g(class)g Fe(seek)p 1185 241 14 2 v 17 w(file)i Fi(that)e(extends)f (the)h(interface)g(of)75 298 y Fe(file)d Fi(with)f(a)g(new)g(operation)f Fe(seek)p Fi(:)75 398 y Fd(class)24 b(seek_file:)g(public)h(virtual)f(file)h ({)224 447 y(public:)274 497 y(virtual)g(unsigned)f(long)g(seek\(unsigned)g (long,)g(int\))h(=0;)75 547 y(};)75 653 y Fi(The)11 b(client-side)f (implementation)f(of)j Fe(seek)p 815 653 V 17 w(file)h Fi(using)c(class)i Fe(rpc)h Fi(would)e(look)h(like)f(the)h(following:)75 753 y Fd(class)24 b(client_rpc_seek_file:)f(public)i(virtual)f(seek_file,)772 803 y(public)h(virtual)f(client_rpc_file)f({)224 852 y(public:)274 902 y(virtual)i(unsigned)f(long)g(seek\(unsigned)g(long)g(position,)g(int)h (direction\))f({)474 952 y(return)g(do_rpc\(method_id\(seek\),)f(position,)h (direction\);)274 1002 y(})75 1052 y(};)125 1158 y Fi(The)8 b(implementation)e(class)i(has)f(to)h(be)g(a)g(subtype)f(of)h(the)g (interface)g(class)f(for)h(the)g(whole)f(scheme)i(to)e(work,)75 1214 y(so)12 b(deriving)g Fe(client)p 458 1214 V 18 w(rpc)p 557 1214 V 17 w(seek)p 682 1214 V 17 w(file)i Fi(from)g Fe(seek)p 1031 1214 V 17 w(file)g Fi(of)o(fers)f(no)f(controversy)m(.)20 b(The)13 b(debatable)75 1271 y(choice)f(is)h(whether)f(it)g(should)f(also)h (inherit)f(from)j Fe(client)p 1065 1271 V 18 w(rpc)p 1164 1271 V 17 w(file)g Fi(or)e(instead)g(use)g(it)h(as)f(a)h(member)m(.)75 1327 y(Let)e(us)g(look)f(at)h(this)f(second)h(alternative:)75 1427 y Fd(class)24 b(client_rpc_file_SI:)g(public)g(file)g({)224 1477 y(public:)274 1527 y(rpc)h(parent_impl;)274 1576 y(virtual)g(int)f (read\(char*)g(buf,)h(int)f(len\))h({)474 1626 y(return)f (parent_impl.do_rpc\(method_id\(read\),)d(buf,)k(len\);)274 1676 y(})274 1726 y(virtual)g(int)f(write\(char*)g(buf,)h(int)f(len\))h({)474 1776 y(return)f(parent_impl.do_rpc\(method_id\(write\),)d(buf,)k(len\);)274 1825 y(})75 1875 y(};)75 1975 y(class)f(client_rpc_seek_file_SI:)f(public)h (seek_file)h({)224 2025 y(public:)274 2075 y(client_rpc_file_SI)e (parent_impl;)274 2124 y(virtual)i(unsigned)f(long)g(seek\(unsigned)g(long)g (position,)g(int)h(direction\))f({)474 2174 y(return)g (parent_impl.parent_impl.do_rpc\(metho)o(d_id\(seek\),)1271 2224 y(position,)g(direction\);)274 2274 y(})274 2324 y(virtual)h(int)f (read\(char*)g(buf,)h(int)f(len\))h({)474 2373 y(return)f (parent_impl.read\(buf,)f(len\);)274 2423 y(})274 2473 y(virtual)i(int)f (write\(char*)g(buf,)h(int)f(len\))h({)474 2523 y(return)f (parent_impl.write\(buf,)f(len\);)274 2573 y(})75 2622 y(};)p eop %%Page: 5 5 bop 125 42 a Fi(This)15 b(second)g(alternative)g(basically)g(forces)h(us)g (to)g(repeat)g(in)f(each)i(subclass)e(all)g(the)h(methods)f(of)h(the)75 98 y(base)f(classes)g(with)f(trivial)g(implementations)f(as)j(shown)e(above.) 28 b(This)14 b(may)i(be)f(acceptable)h(for)f(a)g(small)75 154 y(system)10 b(with)f(a)i(reduced)g(number)g(of)f(classes)g(and)g(methods,)h (but)e(is)h(clearly)h(undesirable)e(in)h(a)h(lar)o(ge)g(system)75 211 y(with)g(many)h(classes)f(and)g(several)h(levels)f(of)h(subtyping.)k (Each)11 b(time)h(a)g(new)g(interface)g(class)f(is)g(derived,)h(its)75 267 y(implementation)h(class)h(has)g(to)h(copy)f(all)g(the)g(methods)g(from)h (the)f(whole)g(class)g(hierarchy)m(,)i(each)f(of)f(them)75 324 y(calling)d(the)h(implementation)e(of)i(the)g(level)g(above.)19 b(Even)11 b(worse,)i(each)f(time)g(an)g(interface)h(class)e(changes,)75 380 y(because)j(a)h(parameter)g(is)f(added)g(or)h(deleted)f(in)g(a)g (function,)h(that)e(change)i(must)f(be)g(propagated)g(by)g(hand)75 437 y(to)g(all)g(the)g(implementation)f(classes)g(that)h(derive)g(from)h (that)e(interface.)26 b(W)l(e)15 b(feel)g(that)e(in)h(practice)h(this)e(is)75 493 y(equivalent)e(to)g(implementing)g(multiple)f(inheritance)i(by)f(hand,)h (instead)f(of)h(letting)f(the)g(compiler)h(do)g(it)f(for)75 550 y(us.)22 b(It)12 b(is)h(interesting)e(to)h(note)h(that)f(this)g(example)h (uses)g(only)f(single-inheritance)e(in)j(the)g(interface)g(classes)75 606 y(and)e(still)f(leads)g(to)h(the)g(use)g(of)g(multiple-inheritance.)75 730 y Ff(2.4)50 b(Consistency)12 b(Between)g(Clients)g(and)g(Servers)75 817 y Fi(The)19 b(consistency)e(between)h(clients)g(and)g(servers)h(is)f (guaranteed)h(by)f(the)h(lattice)f(of)g(interface)h(classes.)75 874 y(Changing)9 b(an)i(interface,)g(by)e(modifying)g(an)i(interface)f (class,)g(af)o(fects)h(the)f(implementations)f(on)g(both)h(sides.)75 930 y(During)d(development)g(this)g(is)g(easil)o(y)g(detected)g(wit)o(h)g (tool)o(s)g(such)g(as)g Fe(make)g Fi(that)g(re-compile)g(all)g(the)g (necessary)75 987 y(\256les.)125 1043 y(T)n(raditionally)f(systems)i(have)g (maintained)f(consistency)g(between)h(clients)f(and)h(servers)g(at)h(the)f (RPC)h(level,)75 1100 y(requiring)f(both)h(sides)f(to)h(be)h(modi\256ed)f(if) h(the)f(messages)g(exchanged)g(between)g(them)h(change.)16 b(W)l(e)10 b(maintain)75 1156 y(this)g(consistency)g(at)i(a)g(higher)f(level) g(of)g(abstraction)f(that)h(we)h(call)f(the)h(service)f(layer)m(.)18 b(Clients)11 b(may)h(remain)75 1213 y(unchanged)k(as)h(long)f(as)h(the)g (interface)g(classes)f(are)i(not)e(modi\256ed,)j(independent)c(of)i(the)g (format)g(of)g(the)75 1269 y(messages)12 b(exchanged)g(with)f(the)h(server)m (.)21 b(If)13 b(the)f(message)g(format)h(changes,)f(clients)f(have)i(to)f(be) g(re-linked)75 1325 y(\(possibly)d(dynamically\))h(with)g(new)i(proxies,)e (but)h(their)f(compiled)h(code)g(remains)g(unchanged.)125 1382 y(In)k(some)g(situations,)f(we)h(found)f(it)h(useful)f(to)h(de\256ne)g (private)g(interfaces)g(between)f(certain)h(client)f(and)75 1438 y(server)e(side)e(implementations.)16 b(One)11 b(example)g(is)g(the)g (implementation)f(of)i(mapped)f(\256les)g(using)f(the)h(Mach)75 1495 y(external)h(memory)h(management)g(facility)m(.)19 b(This)11 b(implementation)g(is)h(fairly)g(complex)g(and)h(requires)f(close)75 1551 y(cooperation)g(between)g(the)h(client)f(proxy)g(and)g(the)h(server)g (object.)21 b(By)13 b(de\256ning)f(a)h(private)g(interface)g(class)75 1608 y(visible)8 b(only)g(by)h(these)g(two)g(implementations)f(we)h(are)h (able)g(to)f(keep)g(them)h(consistent)d(while)i(still)e(shielding)75 1664 y(the)k(client')m(s)g(code)g(from)g(them.)125 1721 y(A)e(private)f (interface)h(class)g(is)g(just)e(like)i(an)g(ordinary)f(interface)h(class,)h (but)e(it)h(is)f(visible)g(only)g(by)g(the)h(server)75 1777 y(and)i(its)g(proxies.)17 b(It)11 b(extends)g(the)g(public)f(interface)i(by)f (de\256ning)g(new)g(methods)g(that)g(are)h(available)f(only)g(to)75 1834 y(the)f(proxy)m(.)15 b(The)10 b(proxy)g(inherits)f(the)g(private)h (interface)g(and)g(the)g(implementation)f(of)h(the)g(default)g(proxy)f(for)75 1890 y(the)i(public)f(interface.)75 2014 y Ff(2.5)50 b(Run-T)o(ime)12 b(Pointer)g(Conversion)75 2101 y Fi(In)h(the)f(previous)f(example,)j(a)f (client)f(that)g(receives)h(an)g(object)e(of)i(type)f Fe(seek)p 1364 2101 14 2 v 18 w(file)i Fi(from)f Fe(open)h Fi(cannot)75 2158 y(use)j(it)g(as)h(such)f(unless)g(the)g(reference)i(is)e(converted)g(to) g(type)g Fe(seek)p 1250 2158 V 17 w(file)p Fi(.)37 b(This)17 b(case)h(is)f(of)h(special)75 2214 y(importance)10 b(in)g(our)h(system)f (because)g(most)g(operations)f(start)h(by)h(looking)d(up)j(an)f(object)g(by)g (name)h(and)g(then)75 2271 y(request)g(operations)f(on)h(it.)17 b(The)11 b(type)g(of)h(the)f(object)f(is)h(not)g(known)g(until)f(it)g(is)h (looked-up)f(in)h(the)g(directory)m(,)75 2327 y(but)d(depending)g(on)h(it)f (dif)o(ferent)h(operations)f(may)h(be)g(performed.)17 b(For)9 b(example,)h(the)f(system)f(contains)g(\256les,)75 2384 y(directories,)i (symbolic)f(links,)h(mount)f(points,)h(pipes,)g(various)f(types)h(of)g (connection)f(endpoints)f(or)j(sockets,)75 2440 y(all)d(of)h(which)e(can)i (be)g(looked-up)e(with)g(the)h(same)h(operation,)g(yet)f(\256les)g(and)g (connection-less)f(sockets)g(require)75 2496 y(dif)o(ferent)k(protocols)f(to) g(read)i(and)f(write)g(data.)125 2553 y(For)h(this)g(reason,)g(we)h(use)f(a)g (type-safe)g(run-time)h(pointer)e(conversion)g(mechanism,)i(similar)f(to)f (the)h(one)75 2609 y(described)g(in[2)o(].)21 b(All)12 b(classes)g(contain)f (a)i Fe(castdown\(clas)q(s)p 1153 2609 V 19 w(id\))h Fi(function)d(that)h (returns)g(the)g(pointer)p eop %%Page: 6 6 bop 75 42 a Fi(to)8 b(the)h(object)f(cast)h(to)g(class)f Fe(class)p 664 42 14 2 v 18 w(id)h Fi(if)g Fe(class)p 917 42 V 18 w(id)h Fi(is)e(a)h(base)g(class)g(of)g(the)f(object)g(\(otherwise)g(it)h(returns)75 98 y(0\).)125 154 y(Clients)17 b(use)i(it)f(as)h(follows:)29 b(the)18 b(name)i(lookup)d(routine)g(returns)h(a)h(generic)g(type)f(that)g (is)g(the)h(least)75 211 y(common)12 b(denominator)e(of)i(all)f(possible)f (types)g(and)i(an)f(indication)f(of)h(the)h(\(interface\))g(class)f(of)g(the) h(object.)75 267 y(Based)19 b(on)e(this)h(information)f(the)h(client)f(then)h (casts)g(the)g(reference)h(to)f(the)g(real)h(interface)f(type)g(of)g(the)75 324 y(object.)32 b(For)17 b(example,)i(if)e(a)g(client)e(had)i(called)f Fe(open)i Fi(and)f(an)f(object)g(of)h(interface)g Fe(seek)p 1639 324 V 17 w(file)h Fi(and)75 380 y(implementation)10 b Fe(client)p 537 380 V 18 w(rpc)p 636 380 V 17 w(seek)p 761 380 V 18 w(file)j Fi(had)e(been)g(returned,)h(the)f(reference)i(would)e(be)g (cast)h(from)75 437 y Fe(file)h Fi(to)e Fe(seek)p 354 437 V 17 w(file)i Fi(and)e(used)g(as)g(such.)17 b(A)12 b(pointer)e(conversion)g (failure)h(generally)g(indicates)f(an)i(error)75 493 y(in)f(the)g(operation)f (of)h(the)g(system.)125 550 y(W)l(e)16 b(only)f(use)g(such)g(pointer)g (conversions)f(in)h(the)h(interface)g(hierarchy)m(.)30 b(In)15 b(the)h(example)g(above,)g(the)75 606 y(real)11 b(type)e(of)i(the)f(object)f (is)h Fe(client)p 684 606 V 18 w(rpc)p 783 606 V 17 w(seek)p 908 606 V 18 w(file)p Fi(,)i(but)e(we)g(convert)g(it)g(from)h(the)f (interface)g(type)g(we)75 663 y(know)g(at)i(compile)e(time)i(\()p Fe(file)p Fi(\))g(to)f(the)g(the)g(one)g(we)g(detect)g(at)g(run-time)g(\()p Fe(seek)p 1412 663 V 18 w(file)p Fi(\).)125 719 y(W)l(e)i(rejected)f(the)g (alternate)g(method)g(of)g(de\256ning)f(all)h(functions)f(in)h(the)g(base)g (class)f(with)h(an)g(implemen-)75 775 y(tation)g(that)g(returns)g(an)h(error) h(because)f(it)f(would)g(force)h(us)g(to)f(modify)g(the)h(base)g(classes)f (whenever)h(a)g(new)75 832 y(class)g(is)f(added.)23 b(In)13 b(our)g(case)g(this)f(is)h(not)f(even)h(possible,)g(as)g(one)g(of)g(our)g (requirements)g(is)f(to)h(not)f(change)75 888 y(existing)d(clients)h(and)h (servers)g(when)g(new)g(services,)g(and)g(hence)h(new)f(classes,)g(are)h (introduced.)75 1032 y Fj(3)60 b(Overview)12 b(of)j(the)g(Class)g(Library)75 1136 y Fi(The)9 b(class)f(library)h(contains)e(the)i(C++)g(classes)f(from)i (which)e(servers)h(are)g(assembled.)16 b(All)8 b(operating)g(system)75 1192 y(entities)i(such)h(as)g(processes,)h(\256les,)f(sockets,)g(are)h (represented)g(by)f(objects)f(and)h(are)i(implemented)e(by)g(these)75 1249 y(classes.)17 b(The)12 b(current)f(prototype)f(provides)h(a)h (self-hosting)d(implementation)h(of)i(Unix)f(BSD)h(4.3.)18 b(Most)11 b(of)75 1305 y(these)f(classes)g(were)g(written)g(from)h(scratch,)f (but)g(a)h(lar)o(ge)f(amount)g(of)g(existing)f(C)h(code)h(is)f(reused)g (\(e.g.)17 b(BSD)75 1361 y(Unix)10 b(File)h(System\).)488 2244 y @beginspecial -70 @hoffset -230 @voffset 60 @hscale 60 @vscale @setspecial %%BeginDocument: x.ps /__NXdef{1 index where{pop pop pop}{def}ifelse}bind def /__NXbdef{1 index where{pop pop pop}{bind def}ifelse}bind def /UserObjects 10 array __NXdef /defineuserobject{ exch dup 1 add dup UserObjects length gt{ array dup 0 UserObjects putinterval /UserObjects exch def }{pop}ifelse UserObjects exch 3 -1 roll put }__NXbdef /undefineuserobject{UserObjects exch null put}__NXbdef /execuserobject{UserObjects exch get exec}__NXbdef /__NXRectPath{4 2 roll moveto 1 index 0 rlineto 0 exch rlineto neg 0 rlineto closepath}__NXbdef /__NXProcessRectArgs{ 1 index type /arraytype eq{ exch 0 4 2 index length 1 sub{ dup 3 add 1 exch{1 index exch get exch}for 5 1 roll 5 index exec }for pop pop }{exec}ifelse }__NXbdef /rectfill{gsave newpath {__NXRectPath fill} __NXProcessRectArgs grestore}__NXbdef /rectclip{newpath {__NXRectPath} __NXProcessRectArgs clip newpath}__NXbdef /rectstroke{ gsave newpath dup type /arraytype eq{dup length 6 eq}{false}ifelse{ {gsave __NXRectPath null concat stroke grestore} dup length array cvx copy dup 2 4 -1 roll put __NXProcessRectArgs }{{__NXRectPath stroke} __NXProcessRectArgs}ifelse grestore }__NXbdef /xyshow{ 0 1 3 index length 1 sub{ currentpoint 4 index 3 index 1 getinterval show 3 index 3 index 2 mul 1 add get add exch 3 index 3 index 2 mul get add exch moveto pop }for pop pop }__NXbdef /xshow{ 0 1 3 index length 1 sub{ currentpoint 4 index 3 index 1 getinterval show exch 3 index 3 index get add exch moveto pop }for pop pop }__NXbdef /yshow{ 0 1 3 index length 1 sub{ currentpoint 4 index 3 index 1 getinterval show 3 index 3 index get add moveto pop }for pop pop }__NXbdef /arct{arcto pop pop pop pop}__NXbdef /setbbox{pop pop pop pop}__NXbdef /ucache{}__NXbdef /ucachestatus{mark 0 0 0 0 0}__NXbdef /setucacheparams{cleartomark}__NXbdef /uappend{systemdict begin cvx exec end}__NXbdef /ueofill{gsave newpath uappend eofill grestore}__NXbdef /ufill{gsave newpath uappend fill grestore}__NXbdef /ustroke{ gsave newpath dup length 6 eq {exch uappend concat}{uappend}ifelse stroke grestore }__NXbdef /__NXustrokepathMatrix dup where {pop pop}{matrix def}ifelse /ustrokepath{ newpath dup length 6 eq{ exch uappend __NXustrokepathMatrix currentmatrix exch concat strokepath setmatrix }{uappend strokepath}ifelse } __NXbdef /upath{ [exch {/ucache cvx}if pathbbox /setbbox cvx {/moveto cvx}{/lineto cvx}{/curveto cvx}{/closepath cvx}pathforall]cvx } __NXbdef /setstrokeadjust{pop}__NXbdef /currentstrokeadjust{false}__NXbdef /selectfont{exch findfont exch dup type /arraytype eq {makefont}{scalefont}ifelse setfont}__NXbdef /_NXCombineArrays{ counttomark dup 2 add index dup length 3 -1 roll { 2 index length sub dup 4 1 roll 1 index exch 4 -1 roll putinterval exch }repeat pop pop pop }__NXbdef /setcmykcolor{ 1.0 exch sub dup dup 6 -1 roll sub dup 0 lt{pop 0}if 5 1 roll 4 -1 roll sub dup 0 lt{pop 0}if 3 1 roll exch sub dup 0 lt{pop 0}if setrgbcolor }__NXbdef /currentcmykcolor{currentrgbcolor 3{1.0 exch sub 3 1 roll}repeat 0}__NXbdef /flushgraphics{}def /setwindowtype{pop pop}def /currentwindowtype{pop 0}def /setalpha{pop}def /currentalpha{1.0}def /hidecursor{}def /obscurecursor{}def /revealcursor{}def /setcursor{4 {pop}repeat}bind def /showcursor{}def /NextStepEncoding where not{ /NextStepEncoding StandardEncoding 256 array copy def 0 [129/Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/Ccedilla/Egrave /Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex/Idieresis /Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis/Ugrave/Uacute /Ucircumflex/Udieresis/Yacute/Thorn/mu/multiply/divide/copyright 176/registered 181/brokenbar 190/logicalnot 192/onesuperior 201/twosuperior 204/threesuperior 209/plusminus/onequarter/onehalf/threequarters/agrave /aacute/acircumflex/atilde/adieresis/aring/ccedilla/egrave/eacute /ecircumflex/edieresis/igrave 226/iacute 228/icircumflex/idieresis/eth /ntilde 236/ograve/oacute/ocircumflex/otilde/odieresis 242/ugrave/uacute /ucircumflex 246/udieresis/yacute 252/thorn/ydieresis] {dup type /nametype eq {NextStepEncoding 2 index 2 index put pop 1 add}{exch pop}ifelse }forall pop /NextStepEncoding NextStepEncoding readonly def /_NXfstr 128 string dup 0 (_NX) putinterval def /findfont{ % Because we can never let NextStepEncoding get into % SharedFontDirectory, we cannot reencode a font to NextStepEncoding % if we are in shared mode. So if currentshared is true, % we call the normal findfont and return that /currentshared where {pop currentshared} {false} ifelse {//findfont exec} {dup _NXfstr 3 125 getinterval cvs length 3 add _NXfstr 0 3 -1 roll getinterval cvn exch FontDirectory 2 index known {pop FontDirectory exch get} {//findfont exec dup /Encoding get StandardEncoding eq { dup length dict exch {1 index /FID ne {2 index 3 1 roll put}{pop pop}ifelse}forall dup /Encoding NextStepEncoding put definefont }{exch pop} ifelse }ifelse }ifelse }bind def }{pop}ifelse /_NXProcArray 5 array __NXdef /_NXChannels 0 __NXdef /_NXTotalBytes 0 __NXdef /_NXDoImageOp{ 1 index{dup}{1}ifelse /_NXChannels exch store _NXChannels 2 add 2 roll _NXProcArray 0 _NXChannels getinterval astore pop 5 index 4 index mul 2 index{1 sub 8 idiv 1 add mul}{mul 1 sub 8 idiv 1 add}ifelse 4 index mul /_NXTotalBytes exch store pop exch pop gsave matrix invertmatrix concat 0.5 setgray 0 0 4 2 roll rectfill grestore { 0 1 _NXChannels 1 sub{ _NXProcArray exch get exec length _NXTotalBytes exch sub /_NXTotalBytes exch store}for _NXTotalBytes 0 le{exit}if }loop /_NXProcArray 5 array def }__NXbdef /colorimage{_NXDoImageOp}__NXbdef /alphaimage{1 add _NXDoImageOp}def /landscape false def /t300 [0.000 0.006 0.011 0.017 0.022 0.028 0.033 0.039 0.045 0.050 0.056 0.061 0.067 0.073 0.078 0.084 0.089 0.095 0.101 0.117 0.133 0.148 0.164 0.179 0.195 0.210 0.225 0.240 0.255 0.270 0.285 0.299 0.314 0.329 0.344 0.359 0.374 0.389 0.404 0.419 0.435 0.451 0.466 0.482 0.498 0.513 0.529 0.544 0.560 0.576 0.591 0.610 0.632 0.654 0.677 0.699 0.721 0.744 0.766 0.788 0.821 0.866 0.911 0.955 1.000 ] def /t400 [0.000 0.003 0.006 0.009 0.012 0.014 0.017 0.020 0.023 0.026 0.029 0.032 0.035 0.038 0.041 0.043 0.046 0.049 0.056 0.063 0.071 0.079 0.087 0.095 0.104 0.117 0.130 0.143 0.157 0.173 0.189 0.205 0.225 0.245 0.259 0.272 0.285 0.298 0.314 0.329 0.345 0.361 0.376 0.392 0.407 0.423 0.439 0.454 0.470 0.486 0.502 0.528 0.554 0.580 0.605 0.628 0.650 0.672 0.695 0.727 0.762 0.796 0.857 0.922 1.000 ] def /tlinear [0.000 0.016 0.031 0.047 0.062 0.078 0.094 0.109 0.125 0.141 0.156 0.172 0.188 0.203 0.219 0.234 0.250 0.266 0.281 0.297 0.312 0.328 0.344 0.359 0.375 0.391 0.406 0.422 0.438 0.453 0.469 0.484 0.500 0.516 0.531 0.547 0.562 0.578 0.594 0.609 0.625 0.641 0.656 0.672 0.688 0.703 0.719 0.734 0.750 0.766 0.781 0.797 0.812 0.828 0.844 0.859 0.875 0.891 0.906 0.922 0.938 0.953 0.969 0.984 1.000 ] def /dmatrix matrix def /desiredpat 0 def /dpi 72 0 dmatrix defaultmatrix dtransform dup mul exch dup mul add sqrt round def /freq dpi 18.75 div 8 div round dup 0 eq { pop 1 } if 8 mul dpi exch div def /sangle 1 0 dmatrix defaultmatrix dtransform exch atan def /graymode true def /pats 16 array def /mymatrix matrix def /savedgray 0 def /F /fill load def /rc /rectclip load def /GS /gsave load def /GR /grestore load def /SL /setlinewidth load def /SC /setlinecap load def /CS { closepath S } bind def /A /strokepath load def /TR /translate load def /M /moveto load def /C /closepath load def /smat { mymatrix currentmatrix pop } bind def /rmat { mymatrix setmatrix } bind def /sp { P exch get exec } bind def systemdict /setshared known { 300 dpi eq { /tran t300 def } { /tran t400 def } ifelse } { /tran tlinear def } ifelse systemdict /xshow known not { /xhow { /pts exch def /str exch def 0 1 str length 1 sub { currentpoint 3 -1 roll str 1 index 1 getinterval show 3 1 roll moveto pts exch get 0 rmoveto } for } bind def } { /xhow { checkink xshow } bind def } ifelse systemdict /xyshow known not { /xyhow { /pts exch def /str exch def 0 1 str length 1 sub { currentpoint 3 -1 roll str 1 index 1 getinterval show 3 1 roll moveto 2 mul pts 1 index get pts 3 -1 roll 1 add get rmoveto } for } bind def } { /xyhow { checkink xyshow } bind def } ifelse /PrintInColor systemdict /colorimage known def PrintInColor { /HUE 0 def /SAT 0 def /BRIGHT 0 def /Colors [[0 0 ] [0 0 ] [0.00 1.0] [0.37 1.0] [0.60 1.0] [0.50 1.0] [0.83 1.0] [0.16 1.0] ] def /K { Colors exch get dup 0 get /HUE exch store 1 get /BRIGHT exch store HUE 0 eq BRIGHT 0 eq and {1.0 SAT sub setgray } {HUE SAT BRIGHT sethsbcolor } ifelse } def /mysetgray { /SAT exch 1.0 exch sub store HUE 0 eq BRIGHT 0 eq and {1.0 SAT sub setgray } {HUE SAT BRIGHT sethsbcolor } ifelse } bind def } { /mysetgray /setgray load def /K /pop load def } ifelse /setpattern { /bwidth exch def /bpside exch def /bstring exch def /onbits 0 def /offbits 0 def freq sangle landscape {90 add} if {/y exch def /x exch def /xindex x 1 add 2 div bpside mul cvi def /yindex y 1 add 2 div bpside mul cvi def bstring yindex bwidth mul xindex 8 idiv add get 1 7 xindex 8 mod sub bitshift and 0 ne {/onbits onbits 1 add def 1} {/offbits offbits 1 add def 0} ifelse } setscreen tran offbits 64 mul offbits onbits add div cvi get mysetgray } bind def /myfonts [] def /procarray 30 array def 3.86 setmiterlimit currentscreen cvlit /orgproc exch def /organgle exch def /orgfreq exch def /currentpat -1 def /checkpat { graymode currentpat desiredpat ne or { pats desiredpat get exec /graymode false store /currentpat desiredpat store } if } bind def /Z { checkpat fill } bind def /checkink { graymode not { orgfreq organgle orgproc cvx setscreen /graymode true store savedgray mysetgray } if } bind def /F { checkink fill } bind def /dorectfill { checkink rectfill } bind def /dorectstroke { checkink rectstroke } bind def /S { checkink stroke } bind def /G { /savedgray exch def savedgray mysetgray } def /makecontextpattern { exch pop [null 8 1 /setpattern cvx] 4 array copy dup 0 5 -1 roll put cvx pats 3 1 roll put } def /P [ 0 1 15 { [ /desiredpat 3 -1 roll /store cvx ] cvx } for ] def /patoffsetx 0 def /patoffsety 0 def /currentpat null def /DiacriticEncoding [ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /less /equal /greater /question /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore /grave /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde /.notdef /Adieresis /Aring /Ccedilla /Eacute /Ntilde /Odieresis /Udieresis /aacute /agrave /acircumflex /adieresis /atilde /aring /ccedilla /eacute /egrave /ecircumflex /edieresis /iacute /igrave /icircumflex /idieresis /ntilde /oacute /ograve /ocircumflex /odieresis /otilde /uacute /ugrave /ucircumflex /udieresis /dagger /.notdef /cent /sterling /section /bullet /paragraph /germandbls /registered /copyright /trademark /acute /dieresis /.notdef /AE /Oslash /.notdef /.notdef /.notdef /.notdef /yen /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /ordfeminine /ordmasculine /.notdef /ae /oslash /questiondown /exclamdown /logicalnot /.notdef /florin /.notdef /.notdef /guillemotleft /guillemotright /ellipsis /.notdef /Agrave /Atilde /Otilde /OE /oe /endash /emdash /quotedblleft /quotedblright /quoteleft /quoteright /.notdef /.notdef /ydieresis /Ydieresis /fraction /currency /guilsinglleft /guilsinglright /fi /fl /daggerdbl /periodcentered /quotesinglbase /quotedblbase /perthousand /Acircumflex /Ecircumflex /Aacute /Edieresis /Egrave /Iacute /Icircumflex /Idieresis /Igrave /Oacute /Ocircumflex /.notdef /Ograve /Uacute /Ucircumflex /Ugrave /dotlessi /circumflex /tilde /macron /breve /dotaccent /ring /cedilla /hungarumlaut /ogonek /caron ] def /DiacriticEncode { /basefontdict exch def /newfontdict basefontdict maxlength 2 add dict def basefontdict {exch dup /FID ne {dup /Encoding eq {exch pop DiacriticEncoding } {exch} ifelse newfontdict 3 1 roll put } {pop pop} ifelse } forall newfontdict } def /line { pop pop pop pop } def /rrectpath { smat 4 2 roll TR /h exch def /w exch def /r exch def mark r 0 M w 0 w h r arcto w h 0 h r arcto 0 h 0 0 r arcto 0 0 w 0 r arcto C cleartomark rmat } def /RF { rrectpath F } bind def /RP { checkpat rrectpath fill } bind def /RS { rrectpath S } bind def /RQ { checkpat rrectpath A fill } bind def /NF { dorectfill } bind def /NR { checkpat 4 2 roll rectfill } bind def /W { savedgray 5 1 roll 1.0 G dorectfill G } bind def /invertbox { pop pop pop pop } def /highbox { pop pop pop pop } def /PP { newpath 3 1 roll M 1 sub { lineto } repeat } bind def /SP { 3 1 roll M 3 div cvi { curveto } repeat } bind def /rectpath { M dup 0 exch rlineto exch 0 rlineto neg 0 exch rlineto C } def /N { dorectstroke } bind def /NQ { checkpat 4 2 roll rectstroke } bind def /drawip { pop pop pop } bind def /eraseip { pop pop pop } bind def /highip { pop pop pop pop } def /insideedgebox { pop pop pop pop pop } def /replbox { pop pop pop pop pop pop } def /pop4 { pop pop pop pop } def /graybox { pop4 } def /darkgraybox { pop4 } def /arcpath { newpath TR /h exch def /w exch def /dth exch def /th exch def 90 th dth add sub 90 th sub dth 0 lt { exch } if 1 h w div neg scale 0 0 w 2 div 5 -2 roll arc } def /AS { smat arcpath rmat S } bind def /AP { checkpat smat arcpath rmat A fill } bind def /AF { smat arcpath 0 0 lineto rmat F } bind def /AQ { checkpat smat arcpath 0 0 lineto rmat fill } bind def /mymakefont { /size exch def /name exch def /i exch def /myfontdict name cvn findfont def myfontdict /Encoding get dup StandardEncoding eq exch /NextStepEncoding where { pop NextStepEncoding eq or }{ pop } ifelse { myfontdict DiacriticEncode /gfontdict exch def /gfontdict (F ) dup 1 i ( ) cvs putinterval cvn gfontdict definefont def } { /gfontdict myfontdict def } ifelse /myfonts [ myfonts aload pop null ] def myfonts i gfontdict [size 0 0 size neg 0 0 ] makefont put } def /FF { myfonts exch get setfont } bind def /CR { initclip newpath 4 2 roll M dup 0 exch rlineto exch 0 rlineto 0 exch neg rlineto C clip newpath } bind def /cliptowindow { initclip } def /beginprintcode { GS newpath 1 setlinewidth 0 SL 0 setlinejoin [] 0 setdash 0 setgray 10 setmiterlimit /FMdicttop countdictstack 1 add def /FMoptop count 7 sub def 200 dict begin TR dup neg scale 0.0 0.0 M } def /endprintcode { count -1 FMoptop {pop pop} for countdictstack -1 FMdicttop {pop end} for GR } def /beginPSInsetprintcode { /pinsetsave save def newpath 1 setlinewidth 0 setlinecap 0 setlinejoin [] 0 setdash 0 setgray 10 setmiterlimit /showpage {} def /FMdicttop countdictstack 1 add def /FMoptop count def 200 dict begin /showimage {} def } def /endPSInsetprintcode { count -1 FMoptop {pop pop} for countdictstack -1 FMdicttop {pop end} for pinsetsave restore } def /cacheimage { /flip exch def /theta exch def /bps exch def /h exch def /w exch def /destHeight exch def /destWidth exch def /destY exch def /destX exch def /rowbytes w bps mul 7 add 8 idiv def /buffer rowbytes string def GS destX destY TR theta rotate flip {destWidth neg destHeight scale} {destWidth destHeight scale} ifelse w h bps [w 0 0 h 0 h ] { currentfile buffer readhexstring pop } bind image GR } def <0f1e3c78f0e1c387> (I14a1f0) 8 makecontextpattern <0f87c3e1f0783c1e> (I14a20c) 9 makecontextpattern (I14a228) 10 makecontextpattern (I14a244) 11 makecontextpattern <8142241818244281> (I14a260) 12 makecontextpattern <03060c183060c081> (I14a27c) 13 makecontextpattern <8040201008040201> (I14a298) 14 makecontextpattern gsave -1 -9 translate /__NXbasematrix matrix currentmatrix def grestore /__NXsheetsavetoken save def 0 0 translate gsave /__NXbasematrix matrix currentmatrix def grestore gsave 0 0 612 792 rectclip [1 0 0 -1 0 792] concat 0 0 translate gsave 0 0 612 792 rectclip /landscape false def 0 0 612 792 CR 1 G 72 72 495 540 NF 0 G 0 (Times-Bold) 18 mymakefont 0 FF 72 84 M ( ) [0.0 0] xhow 82.125 89.999954 474.75 522.000061 CR 1 G 82.125 89.999954 474.75 522.000061 NF 82.125 98.999954 495 396 NF 0 G 1 (NewCenturySchlbk-Roman) 14 mymakefont 1 FF 82.12 108.33 M (usItem ) [8.549 6.478 5.695 5.443 6.996 12.439 0] xhow 172.12 108.33 M (usName ) [8.549 6.478 11.404 7.78 12.439 6.996 0] xhow 280.12 108.33 M (usNetName ) [8.549 6.478 11.404 6.996 5.443 11.404 7.78 12.439 6.996 0] xhow 82.12 140.33 M ( ) [0] xhow 172.12 140.33 M (usNetBase ) [8.549 6.478 11.404 6.996 5.443 10.102 7.78 6.478 6.996 0] xhow 280.12 140.33 M (usNetConnector ) [8.549 6.478 11.404 6.996 5.443 10.102 6.996 8.549 8.549 6.996 6.213 5.443 6.996 6.213 0.0 0] xhow 82.12 172.33 M ( ) [0] xhow 172.12 172.33 M ( ) [0] xhow 82.12 204.33 M ( ) [0] xhow 172.12 204.33 M (usRecIO ) [8.549 6.478 10.102 6.996 6.213 5.695 10.886 0] xhow 280.12 204.33 M (usNetCLTS ) [8.549 6.478 11.404 6.996 5.443 10.102 8.563 9.333 8.815 0] xhow 424.12 204.33 M (usNetCLTS_recs ) [8.549 6.478 11.404 6.996 5.443 10.102 8.563 9.333 8.815 6.996 6.213 6.996 6.213 6.478 0] xhow 82.12 236.33 M ( ) [0] xhow 82.12 268.33 M ( ) [0] xhow 172.12 268.33 M (usByteIO ) [8.549 6.478 10.102 7.514 5.443 6.996 5.695 10.886 0] xhow 280.12 268.33 M (usNetCOTS ) [8.549 6.478 11.404 6.996 5.443 10.102 10.886 9.333 8.815 0] xhow 424.12 268.33 M ( usNetCOTS_recs ) [0.0 8.549 6.478 11.404 6.996 5.443 10.102 10.886 9.333 8.815 6.996 6.213 6.996 6.213 6.478 0] xhow 82.12 300.33 M ( ) [0] xhow 154.12 300.33 M ( ) [0] xhow 244.12 300.33 M ( ) [0] xhow 424.12 300.33 M (usNetCOTS_bytes ) [8.549 6.478 11.404 6.996 5.443 10.102 10.886 9.333 8.815 6.996 7.78 7.514 5.443 6.996 6.478 0] xhow 82.12 332.33 M ( ) [0] xhow 172.12 332.33 M (usTask ) [8.549 6.478 8.465 7.78 6.478 8.297 0] xhow 82.12 364.33 M ( ) [0] xhow 172.12 364.33 M (usSys ) [8.549 6.478 8.815 7.514 6.478 0] xhow 82.12 396.33 M ( ) [0] xhow 172.12 396.33 M (usEvent ) [8.549 6.478 10.102 7.514 6.996 8.549 5.443 0] xhow 148.66 111.31 137.12 108 148.66 104.69 148.66 108 4 PP F 148.66 108 164.62 108 2 PP 0.5 SL 3.86 setmiterlimit S 249.49 111.31 237.96 108 249.49 104.69 249.49 108 4 PP F 249.49 108 274.62 108 2 PP S 267.83 138.31 256.29 135 267.83 131.69 267.83 135 4 PP F 267.83 135 274.62 135 2 PP S 257.9 146.89 256.29 135 263.96 144.23 260.93 145.56 4 PP F 260.93 145.56 283.79 198 2 PP S 143.08 118.42 137.12 108 147.69 113.68 145.38 116.05 4 PP F 145.39 116.05 164.62 135 2 PP S 138.44 119.93 137.12 108 144.56 117.42 141.5 118.67 4 PP F 141.5 118.67 173.79 198 2 PP S 136.65 119.99 137.12 108 143.07 118.42 139.86 119.2 4 PP F 139.86 119.21 173.79 261 2 PP S 255.56 146.98 256.29 135 262.01 145.54 258.78 146.26 4 PP F 258.79 146.26 283.79 261 2 PP S 386.99 201.31 375.46 198 386.99 194.69 386.99 198 4 PP F 386.99 198 421.29 198 2 PP S 386.99 264.31 375.46 261 386.99 257.69 386.99 261 4 PP F 386.99 261 421.29 261 2 PP S 382.44 270.75 375.45 261 386.55 265.56 384.49 268.15 4 PP F 384.5 268.16 421.29 297 2 PP S 244.25 208.18 237.95 198 248.69 203.3 246.47 205.74 4 PP F 300.96 229.61 269.4 223.88 246.49 205.76 395.15 213.27 361.02 218.7 330.03 224.33 421.29 198 7 SP S 247.78 204.89 237.95 198 249.94 198.64 248.86 201.76 4 PP F 248.86 201.77 421.29 261 2 PP S 257.73 266.6 247.12 260.99 259.09 260.12 258.41 263.36 4 PP F 258.41 263.37 421.29 297 2 PP S 263.64 129.23 253.11 135 258.98 124.53 261.31 126.88 4 PP F 280.12 108 261.32 126.88 2 PP S 134.78 119.92 136.12 108 141.3 118.83 138.04 119.38 4 PP F 138.04 119.38 172.12 324 2 PP S 134.49 119.89 136.12 108 141.04 118.95 137.77 119.42 4 PP F 137.77 119.42 172.12 360 2 PP S 134.33 119.86 136.12 108 140.89 119.01 137.61 119.44 4 PP F 137.61 119.44 172.12 387 2 PP S grestore grestore showpage __NXsheetsavetoken restore %%EndDocument @endspecial 714 2342 a(Figure)g(1:)16 b(Interface)c(classes.)125 2444 y(The)j(hierarchy)g(of)g(interface)g(classes)g(is)g(represented)g(in)f (Fig.)i(1.)28 b(All)14 b(classes)h(have)g(a)h(common)f(base)75 2501 y Fe(usItem)g Fi(that)d(de\256nes)g(a)h(protocol)f(available)g(to)g(all) g(objects.)20 b(The)13 b(next)f(level)g(de\256nes)h(the)f(interfaces)h(for)75 2557 y(most)c(of)g(the)f(objects.)15 b(For)10 b(example,)g Fe(usName)h Fi(is)d(used)h(for)g(directories,)g Fe(usByteIO)i Fi(for)e(\256les,)h Fe(usRecIO)75 2614 y Fi(for)15 b(connectionless)d (sockets,)i Fe(usTask)i Fi(for)f(process)f(control,)g Fe(usSys)i Fi(for)f(con\256guration)e(management)75 2670 y(and)k Fe(usEvent)i Fi(for)e(signals.)33 b(Class)17 b Fe(usNetbase)j Fi(and)d(all)g(the)g(other)f (interface)i(classes)e(are)i(used)f(to)p eop %%Page: 7 7 bop 75 42 a Fi(describe)13 b(the)f(networking)f(interfaces,)j(which)e(may)h (be)g(connectionless)e(and)i(record)g(oriented)f(\(e.g.)22 b(UDP)75 98 y(sockets\),)16 b(connection)e(oriented)g(and)h(record)h (oriented,)f(or)h(connection)e(oriented)g(and)h(byte-stream)g(\(e.g.)75 154 y(TPC/IP)d(sockets\).)125 211 y(Interface)18 b(class)f Fe(usByteIO)j Fi(describes)c(the)h(protocol)f(for)i(byte-stream)f (input/output)o(.)33 b(It)17 b(has)g(four)75 267 y(dif)o(ferent)e(server)o (-side)g(implementations)f(for)i(\256les,)h(pipes,)f(ttys)e(and)h(sockets.)29 b(There)15 b(are)h(two)f(dif)o(ferent)75 324 y(proxies)e(for)h(this)f (interface,)i(a)f(simple)f(proxy)h(that)f(sends)g(messages)h(for)g(each)g (operation)f(and)h(is)f(used)h(by)75 380 y(pipes,)f(tty)f(and)h(sockets,)f (and)h(a)g(complex)g(one)g(that)f(implements)g(mapped)h(\256les.)22 b(From)14 b(the)e(client')m(s)h(point)75 437 y(of)e(view)g(all)g(these)g (implementations)e(are)j(absolutely)d(equivalent.)125 493 y(Interface)i (class)f Fe(usName)i Fi(de\256nes)f(a)f(naming)g(protocol)g(to)g(lookup)e (objects)i(by)g(name,)i(insert)d(and)h(delete)75 550 y(them)16 b(in)g(a)g(directory)m(,)h(mount)e(one)h(naming)g(hierarchy)f(on)h(another)g (and)f(link)g(two)h(naming)f(hierarchies.)75 606 y(There)k(are)g(three)g (server)o(-side)f(implementation)f(classes)h(that)g(implement)g(volatile)f (directories,)j(mount)75 663 y(points)8 b(and)i(symbolic)e(links,)h(and)h (several)g(others)f(that)g(implement)g(persistent)g(directories)g(in)g(the)g (Unix)g(File)75 719 y(System.)17 b(Class)10 b Fe(usName)j Fi(is)e(also)g(a)g (base)g(class)g(for)h(the)e(networking)g(naming)h(class)f Fe(usNetName)p Fi(.)125 775 y(Interface)17 b(class)g Fe(usTask)h Fi(de\256nes)f(the)f (protocol)g(for)h(process)f(management.)34 b(It)17 b(currently)f(has)g(one)75 832 y(server)o(-side)11 b(implementation)e(and)i(three)g(proxies,)f(the)h (default)f(one)g(that)h(sends)f(messages)h(for)g(each)g(opera-)75 888 y(tion)f(and)h(two)f(others)g(that)h(cache)g(certain)g(characteristics)g (of)g(the)f(process)h(\(e.g.)17 b(pid,)11 b(session)e(identi\256er\))i(to)75 945 y(avoid)f(contacting)g(the)h(server)m(.)125 1001 y(The)h(complete)f (description)g(of)h(all)f(the)h(interfaces)g(and)f(implementations)g(is)g (beyond)g(the)h(scope)f(of)h(this)75 1058 y(paper)m(.)30 b(W)l(e)16 b(currently)e(have)i(the)f(\256fteen)g(interface)h(classes)f(represented)g (in)f(the)h(\256gure,)i(eighteen)e(proxy)75 1114 y(classes,)k(about)d(thirty) g(server)o(-side)h(implementations)f(and)h(over)g(twenty)f(other)h(classes)g (internal)g(to)f(the)75 1171 y(servers.)g(Several)c(others)f(are)g(still)f (being)g(developed.)75 1317 y Fj(4)60 b(The)14 b(Remote)g(Object)g (Invocation)g(Mechanism)75 1420 y Fi(The)g(remote)g(object)f(invocation)f (subsystem)h(consists)f(of)i(an)g(RPC)h(package)f(extended)f(with)g(a)h (layer)g(that)75 1476 y(handles)h(object)g(references.)32 b(An)15 b(unusual)g(characteristic)g(of)h(our)f(RPC)i(is)f(that)f(there)h(are)g(no)g (compiled)75 1533 y(stubs.)g(Instead,)11 b(each)h(function)e(is)h(described)g (by)g(a)g(data)h(structure)e(that)h(is)g(parsed)g(at)h(run-time)f(by)g(a)g (single)75 1589 y(pair)g(of)g(routines.)125 1646 y(This)f(section)h (describes)g(how)g(the)g(type)g(information)f(necessary)i(to)f(format)h (messages)f(is)g(speci\256ed)g(and)75 1702 y(the)h(mechanics)g(of)h (transferring)e(object)h(references)h(in)f(messages,)h(instantiating)c (proxies)i(and)i(distributed)75 1759 y(garbage)e(collection.)75 1883 y Ff(4.1)50 b(RPC)13 b(Interface)75 1970 y Fi(The)8 b(abstract)f (classes)g(described)g(in)g(the)h(previous)e(sections)h(completely)g (de\256ne)h(the)f(C++)h(interface)g(between)75 2026 y(clients)h(and)g (servers.)16 b(If)10 b(no)f(actual)h(communication)e(took)h(place,)h(they)g (would)e(provide)h(all)g(the)g(information)75 2083 y(necessary)j(for)g (clients)f(and)h(servers)h(to)e(interact.)19 b(As)12 b(this)f(is)h(not)f(the) h(case,)i(we)e(need)g(to)g(specify)f(the)h(RPCs)75 2139 y(exchanged)f (between)g(clients)f(and)h(servers.)125 2196 y(In)20 b(our)f(library)h(the)f (abstract)h(class)f(de\256ning)g(an)h(interface)g(also)g(speci\256es)f(the)h (RPCs)h(that)e(can)h(be)75 2252 y(exchanged)13 b(between)h(a)g(client)g(of)g (the)f(class)h(and)f(the)h(server)g(implementing)f(it.)24 b(Each)14 b(member)h(function)75 2309 y(of)f(an)f(abstract)g(class)h(may)g(correspond)e (to)h(a)h(message.)24 b(The)14 b(abstract)f(class)g(must)g(therefore)h (contain)e(the)75 2365 y(information)c(describing)f(the)i(parameters)g(to)g (each)g(member)h(function)d(so)i(that)f(messages)h(can)g(be)g(generated.)75 2422 y(Implementation)16 b(classes)h(inherit)f(these)h(descriptions,)g(so)g (by)g(default)f(they)h(are)h(able)f(to)g(communicate)75 2478 y(through)11 b(RPC.)i(They)f(may)g(rede\256ne)h(or)f(ignore)f(this)g (information)g(if)h(their)f(message)h(interface)h(happens)e(to)75 2534 y(be)g(dif)o(ferent.)125 2591 y(Since)i(we)f(have)h(no)f(other)g(tools)f (available,)i(we)g(require)f(the)g(programmer)i(to)e(specify)g(the)g(RPCs)h (using)75 2647 y(a)j(set)f(of)g(macros)h(and)f(functions)f(in)h(both)f(the)h (interface)h(declaration)e(and)i(implementation)d(\256les.)30 b(They)p eop %%Page: 8 8 bop 75 42 a Fi(generate)17 b(a)g(data)g(structure)f(with)g(type)g (information)g(for)h(the)g(class)f(in)h(the)f(form)i(of)e(a)i(table)e (containing)75 98 y(for)d(each)h(function)e(the)h(function)e(identi\256er)n (,)j(the)f(description)e(of)i(the)g(parameters)h(and)f(the)g(address)f(of)h (the)75 154 y(function.)22 b(This)12 b(type)h(information)f(is)h(parsed)g(at) g(run-time)g(by)g(the)g(RPC)i(package)e(to)g(generate)g(messages)75 211 y(and)i(to)g(dispatch)f(incoming)g(calls.)28 b(There)15 b(are)h(no)f(compiled)g(stubs)e(in)i(the)g(traditional)e(sense,)k(instead)d (a)75 267 y(single)9 b(pair)h(of)h(routines)e(scan)h(the)g(type)g (description)f(of)h(the)g(function)g(and)g(pack)g(or)h(unpack)e(the)i (parameters)75 324 y(accordingly)m(.)125 380 y(The)g(complete)g(version)f(of) h(class)g Fe(naming)i Fi(presented)e(in)f(section)g(2)h(would)f(now)h(be:)75 469 y Fd(//)25 b(file)f(naming.h)75 518 y(class)g(naming)h({)224 568 y(public:)274 618 y(virtual)g(int)f(open\(char*,)g(file**\))g(=0;)75 668 y(};)75 718 y(EXPORT_METHOD\(open\);)75 806 y(//)h(file)f(naming.cc)75 856 y(#include)g()75 905 y(DEFINE_ABSTRACT_CLASS\(naming\);)75 955 y(DEFINE_METHOD_ARGS\(open,)f("rpc:)h(IN)h(string;)f(OUT)h(*)g (object;"\);)125 1050 y Fi(File)15 b Fe(naming.h)i Fi(contains)d(the)h (abstract)g(class)g(de\256nition,)g(as)g(seen)g(before,)i(and)e(the)g (declaration)f(of)75 1107 y(the)g(functions)e(exported)h(to)g(the)h(RPC)g (package.)25 b(Macro)15 b Fe(EXPORT)p 1202 1107 14 2 v 18 w(METHOD)g Fi(declares)f(a)g(structure)f(with)75 1163 y(the)k(method)g(descriptor)f (that)g(uniquely)g(identi\256es)g(and)h(describes)f(function)g Fe(open)j Fi(in)d(class)h Fe(naming)p Fi(.)75 1220 y(File)g Fe(naming.cc)i Fi(contains)c(the)h(description)f(of)i(the)f(RPCs.)34 b(Macro)17 b Fe(DEFINE)p 1459 1220 V 18 w(ABSTRACT)p 1693 1220 V 19 w(CLASS)75 1276 y Fi(initializes)11 b(the)h(static)g(member)i(that)f (contains)e(the)i(class')f(type)h(information)e(\(e.g.)23 b(class)12 b(name,)i Fe(typeid)75 1333 y Fi(used)g(for)g(pointer)f(conversion\).)25 b(Macro)15 b Fe(DEFINE)p 933 1333 V 18 w(METHOD)p 1113 1333 V 18 w(ARGS)g Fi(initializes)e(the)g(method)h(descriptor)75 1389 y(for)d Fe(open)h Fi(with)d(a)i(string)f(describing)f(the)h(type)g(of)h (its)e(parameters.)17 b(W)l(e)12 b(still)d(have)h(to)g(initialize)f(the)i (method)75 1445 y(descriptor)i(with)g(the)h(address)g(of)g(the)g(function)e (and)i(enter)h(it)e(in)h(the)g(per)o(-class)g(table.)24 b(As)14 b(functions)f(may)75 1502 y(be)f(rede\256ned)h(in)f(subclasses,)g(this)f (cannot)h(be)g(done)g(statically)m(.)18 b(Instead,)13 b(implementation)e (classes)g(have)i(a)75 1558 y(function)d Fe(init)p 349 1558 V 17 w(class)j Fi(that)e(initializes)e(all)i(exported)f(functions)f(as)j (follows:)75 1647 y Fd(//)25 b(file)f(naming_proxy.h)75 1696 y(#include)g()75 1746 y(class)g(naming_proxy:)g(public)g(virtual)h (naming,)f(public)g(virtual)h(rpc)f({)224 1796 y(public:)274 1846 y(virtual)h(int)f(open\(char*,)g(file**\);)75 1896 y(};)75 1984 y(//)h(file)f(naming_proxy.cc)75 2034 y(#include)g()75 2084 y(DEFINE_CLASS\(naming_proxy\);)75 2133 y(void)h (naming_proxy::init_class\(void\))75 2183 y({)274 2233 y(//)g(initialize)f (base)g(classes)h(if)f(any)274 2283 y (BEGIN_SETUP_METHOD_WITH_ARGS\(naming_proxy)o(\);)274 2333 y(SETUP_METHOD_WITH_ARGS\(naming_proxy,open\))o(;)274 2382 y(END_SETUP_METHOD_WITH_ARGS;)75 2432 y(})75 2521 y(int)h (naming_proxy::open\(char)d(*name,)j(file)f(**f\))75 2570 y({)274 2620 y(return)h(do_rpc\(method_id\(open\),)d(name,)j(f\);)75 2670 y(})p eop %%Page: 9 9 bop 125 42 a Fi(The)15 b(call)h(to)f(macro)h Fe(SETUP)p 611 42 14 2 v 18 w(METHOD)p 791 42 V 18 w(WITH)p 917 42 V 17 w(ARGS)h Fi(initializes)d(the)h(various)f(\256elds)i(of)f(the)h(method)75 98 y(descriptor)c(for)i Fe(open)p Fi(:)21 b(a)14 b(per)o(-process)f(unique)f (value)h(to)g(be)g(used)g(as)g(identi\256er)n(,)h(a)g(parsed)f(version)f(of)h (the)75 154 y(string)g(that)h(is)h(easier)f(and)h(faster)g(to)f(manipulate)g (at)g(run-time)h(and)f(the)g(pointer)g(to)g(the)h(function.)25 b(It)15 b(also)75 211 y(enters)d(the)h(method)f(descriptor)f(in)h(the)h(per)o (-class)f(function)f(table,)i(overriding)e(any)i(that)f(might)g(already)g(be) 75 267 y(there.)19 b(Base)13 b(classes)f(are)g(initialized)f(\256rst,)h(so)g (that)f(the)h(function)f(associated)g(with)g(the)h(function)f(identi\256er)75 324 y(is)h(the)h(one)g(of)g(the)g(most)f(derived)h(class,)g(which)f(is)h(the) f(desired)h(behavior)f(for)h(virtual)f(functions.)20 b(For)13 b(this)75 380 y(reason)e(we)g(only)g(support)e(remote)j(invocation)d(of)i (virtual)f(functions.)125 437 y(The)f(function)g Fe(do)p 424 437 V 17 w(rpc)p Fi(,)i(that)e(is)g(used)g(by)h(the)f(client-side)f(classes)i (to)f(invoke)f(a)i(remote)h(operation,)e(is)g(de-)75 493 y(\256ned)h(in)g(a)g (base)g(class)g(and)f(handles)h(all)f(outgoing)f(messages.)16 b(The)10 b(\256rst)g(parameter)h Fe(method)p 1612 493 V 18 w(id\(open\))75 550 y Fi(is)j(really)f(the)h(address)g(of)g(the)f(method)h (descriptor)f(for)h Fe(open)p Fi(.)27 b Fe(do)p 1196 550 V 16 w(rpc)16 b Fi(parses)d(the)h(method)g(descriptor)n(,)75 606 y(extracts)h(the)g(parameters)h(from)g(the)g(stack,)g(constructs)e(the)h (message,)i(performs)f(the)f(RPC,)i(extracts)e(the)75 663 y(output)d (parameters)h(from)h(the)f(message)g(and)g(returns)g(them)g(on)g(the)g (stack.)22 b(For)13 b(the)g(server)o(-side)g(the)g(RPC)75 719 y(does)j(a)i(similar)e(set)h(of)f(operations.)33 b(No)16 b(server)o(-side)h (stub)f(is)g(necessary)h(since)f(the)h(description)e(in)h(the)75 775 y(method)11 b(descriptor)f(is)h(enough)f(to)g(unpack)h(the)g(incoming)f (messages)h(and)g(pack)g(the)g(replies.)75 900 y Ff(4.2)50 b(RPC)13 b(Implementation)75 987 y Fi(The)h(remote)h(invocation)d(mechanism)j (depends)e(heavily)g(on)h(the)g(underlying)f(Mach)h(3.0)h(kernel[1)o(].)26 b(The)75 1043 y(relevant)14 b(Mach)h(abstractions)e(for)i(this)f(discussion)e (are)j(Mach)g(ports,)g(port)f(rights)f(and)i(messages.)26 b(Mach)75 1100 y(ports)13 b(are)h(unidirectional)e(communication)h(channels)g(between)g (processes.)24 b(Port)14 b(rights)e(are)j(capabilities)75 1156 y(allowing)10 b(speci\256c)h(rights)f(\(e.g.)17 b(send,)11 b(receive\))h(of)f(access)h(to)f(a)g(port.)17 b(They)10 b(have)i(32)e(bit)h (names)g(unique)g(in)75 1213 y(an)f(address)g(space.)16 b(Messages)10 b(are)h(typed)e(collections)f(of)i(data)g(passed)f(between)h(processes.)16 b(Messages)9 b(are)75 1269 y(sent)g(to)g(ports)g(and)h(can)g(carry)g(port)f (rights,)h(along)f(with)f(other)i(basic)f(types)g(such)g(as)h(integers)f(and) g(characters.)125 1325 y(Each)g(object)f(exported)h(to)g(clients)f(is)g (associated)h(with)f(a)h(Mach)h(port.)15 b(The)10 b(server)f(that)f(creates)i (the)f(object)75 1382 y(holds)f(a)i(receive)f(right)g(to)g(that)f(port,)i (and)f(each)h(client)e(that)h(is)g(given)f(access)i(to)f(the)g(object)g (holds)f(a)h(send)g(right)75 1438 y(to)k(it.)23 b(Initially)m(,)12 b(objects)h(are)h(created)g(in)f(the)g(server)h(with)e(no)h(associated)f (ports.)23 b(The)13 b(remote)h(invocation)75 1495 y(subsystem)8 b(creates)j(a)f(Mach)g(port)f(for)h(each)h(object)e(the)g(\256rst)h(time)g (that)f(this)f(object)h(is)h(returned)f(as)h(an)g(output)75 1551 y(parameter)i(in)f(a)g(remote)h(invocation.)125 1608 y(Clients)f(send)g (messages)h(to)f(the)h(port)f(that)g(identi\256es)g(the)g(server)h(object.)18 b(A)12 b(message)g(contains)e(a)i(string)75 1664 y(specifying)e(the)h(name)h (of)f(the)g(function)f(being)h(invoked,)f(its)h(parameters)h(and)f(a)h(port)f (indicating)e(where)i(the)75 1721 y(reply)f(should)f(be)h(sent)g(by)g(the)h (server)m(.)17 b(Simple)10 b(types)g(are)h(passed)f(by)g(value.)16 b(Objects)9 b(are)j(represented)e(by)g(a)75 1777 y(tuple)g(composed)h(of)g (the)g(Mach)h(port)f(associated)f(with)g(the)h(object)f(and)h(the)g(name)h (of)f(the)g(proxy)g(class)f(to)h(be)75 1834 y(instantiated)e(at)i(the)g (destination)e(if)i(the)g(object)f(does)h(not)g(exist)f(there.)125 1890 y(T)m(ypically)m(,)e(messages)h(sent)f(from)i(clients)e(to)g(servers)h (pass)g(basic)f(types)h(as)g(input)e(parameters)j(and)f(receive)75 1946 y(objects)g(as)h(output)f(parameters.)17 b(Let)10 b(us)f(use)h(the)g Fe(open)h Fi(function)e(is)h(class)g Fe(naming)h Fi(with)f(implementation)75 2003 y Fe(naming)p 240 2003 V 18 w(proxy)16 b Fi(as)f(an)g(example.)28 b(The)14 b(proxy)g(class)h(simply)f(formats)g(the)h Fe(open)h Fi(message)f(using)e(the)75 2059 y(information)e(stored)g(in)g(the)h(method)f (descriptor)g(and)h(sends)f(it)g(to)g(the)h(port)f(stored)g(in)h(its)f (instance)g(data)g(\(let)75 2116 y(us)h(assume)g(that)f(it)g(had)h(been)g (initialized)e(to)i(reference)h(the)e(directory)h(service\).)19 b(On)11 b(the)h(server)g(the)g(object)75 2172 y(identi\256ed)h(by)h(the)g (port)g(is)g(obtained)f(from)i(the)f(table)g Fe(port)p 1082 2172 V 17 w(to)p 1153 2172 V 17 w(object)p 1332 2172 V 18 w(table)p Fi(,)j(the)e(function)e(name)75 2229 y(is)h(searched)h(and)f(its)g(address)g (is)g(obtained.)26 b(The)14 b(stack)h(frame)g(is)g(constructed)e(as)i (described)e(earlier)i(and)75 2285 y(function)10 b Fe(open)i Fi(at)f(the)g(server)h(is)e(called.)125 2342 y(When)16 b(this)f(function)g (returns,)j(the)e(remote)h(invocation)d(subsystem)h(creates)i(a)g(port)e(to)h (represent)g(the)75 2398 y(return)11 b(parameter)g(and)g(uses)f(a)h(callback) g(to)f(store)h(it)f(in)g(the)h(object.)16 b(It)10 b(uses)h(another)f (callback)g(to)h(obtain)e(the)75 2455 y(name)h(of)g(the)f(proxy)g(class)g (and)h(sends)e(the)i(tuple)e Fe(\(port,)29 b(proxy)g(class\))11 b Fi(in)e(the)h(reply)m(.)15 b(It)10 b(also)f(stores)75 2511 y(the)i(port)f(in)h(the)g(table)g Fe(port)p 551 2511 V 17 w(to)p 622 2511 V 17 w(object)p 801 2511 V 18 w(table)i Fi(for)e(later)g(lookups.) 125 2567 y(At)e(the)g(client,)g(the)g(message)h(is)e(scanned)h(and)g(the)g (return)g(frame)i(is)e(constructed.)14 b(When)9 b(the)g(object)g(refer)o(-)75 2624 y(ence)e(is)g(found,)f(the)h(\(unique\))g(port)g(name)g(is)g(us)o(ed)g (to)f(locate)h(t)o(he)g(ob)o(ject)g(in)f(tabl)o(e)h Fe(port)p 1452 2624 V 15 w(to)p 1521 2624 V 17 w(object)p 1700 2624 V 18 w(table)p Fi(.)p eop %%Page: 10 10 bop 75 42 a Fi(If)15 b(the)g(object)f(exists,)h(its)e(pointer)h(is)h (returned;)g(if)g(not,)g(the)g(name)g(of)g(the)g(proxy)f(class)g(is)g(used)h (to)f(search)75 98 y(another)9 b(table)f(called)h Fe(class)p 574 98 14 2 v 18 w(map)h Fi(and)f(obtain)f(a)i(pointer)e(to)g(an)i(object)e (of)h(the)g(proxy)f(class.)16 b(This)8 b(instance)75 154 y(is)h(used)h(as)g (a)g(\252factory\272)g(to)f(create)i(a)f(new)g(instance)f(of)h(the)g(proxy)f (class.)15 b(The)10 b(proxy)f(object)g(is)h(initialized,)e(s-)75 211 y(toring)f(the)i(Mach)g(port)f(in)g(its)g(instance)g(data,)h(and)g(its)f (pointer)f(is)h(returned)h(to)f(the)g(client.)15 b(T)m(able)8 b Fe(class)p 1748 211 V 18 w(map)75 267 y Fi(is)k(set-up)f(statically)g(at)h (initialization)e(time)i(and)g(contains)f(one)h(instance)g(of)g(each)h(proxy) f(class,)g(associated)75 324 y(with)e(the)h(class)g(name.)125 380 y(When)f(the)h(client)f(later)g(invokes)f(an)i(operation)f(on)g(the)h (proxy)m(,)f(it)g(simply)g(formats)h(a)g(message)f(and)h(sends)75 437 y(it)f(to)g(the)h(associated)f(Mach)h(port,)g(repeating)f(the)g(process)h (just)e(described.)16 b(The)11 b(port)f(representing)f(the)i(root)75 493 y(of)g(the)g(directory)g(service)g(is)f(obtained)g(by)h(clients)f(at)h (initialization)d(time)k(using)e(a)h(well-known)f(port)g(name.)125 550 y(The)j(use)f(of)h(multiple-inheritance)e(together)h(with)g(our)h (run-time)g(parser)g(complicates)f(this)g(implemen-)75 606 y(tation)g(because)h(pointers)e(to)i(objects)f(received)h(as)g(parameters)g (have)g(to)g(be)g(cast)f(to)h(the)f(type)h(speci\256ed)g(by)75 663 y(the)j(interface.)31 b(This)15 b(cast)h(is)g(done)f(once)i(again)e (using)g(the)h(pointer)f(conversion)g(mechanism)h(described)75 719 y(previously)m(.)f(In)d(the)f(method)f(descriptor)n(,)h(the)g (description)f(of)h(the)g(parameters)h(contains)e(the)h(type)g(to)g(which)75 775 y(the)g(object)f(should)f(be)i(cast.)16 b(At)11 b(initialization)d(time)i (we)h(store)g(there)g(the)f Fe(typeid)j Fi(of)e(that)f(class)g(and)h(use)g (it)75 832 y(to)g(perform)g(the)g(pointer)g(conversion)e(at)j(run-time.)75 956 y Ff(4.3)50 b(Garbage)12 b(Collection)75 1043 y Fi(Garbage)j(collection)e (is)h(greatly)h(facilitated)e(by)i(the)f(use)h(of)f(the)h(Mach)g(IPC)h (system.)27 b(Mach)15 b(generates)g(a)75 1100 y(noti\256cation)8 b(message)i(when)f(there)h(are)g(no)f(more)h(send)g(rights)e(outstanding)f (for)j(the)f(port,)h(thereby)f(allowing)75 1156 y(the)h(server)g(to)f (destroy)g(the)g(associated)g(object.)15 b(Clients)9 b(and)h(servers)f (garbage)h(collect)f(their)h(objects)e(locally)75 1213 y(using)k(reference)i (counting.)19 b(When)13 b(a)g(Mach)h(port)e(is)g(\256rst)h(associated)f(with) g(a)h(server)g(object)f(its)g(reference)75 1269 y(count)c(is)g(incremented)h (to)f(account)h(for)g(all)f(remote)h(proxies.)15 b(When)9 b(the)f(reference)i (count)e(on)h(a)g(proxy)f(object)75 1325 y(comes)k(to)g(zero,)g(the)g (associated)f(Mach)i(port)e(is)g(deallocated)g(and)h(the)g(proxy)f(is)g (destroyed.)18 b(When)11 b(the)h(last)75 1382 y(port)g(associated)f(with)g (the)i(object)e(is)h(destroyed,)g(Mach)h(sends)e(a)i(noti\256cation)e (message)h(to)g(the)g(server)h(that)75 1438 y(then)c(decrements)h(the)g (reference)h(count)e(on)h(the)f(object.)16 b(If)10 b(it)f(is)h(the)f(last)h (reference)h(the)e(object)h(is)f(destroyed,)75 1495 y(otherwise)h(the)h (object)f(will)h(be)g(deallocated)f(when)h(there)g(are)h(no)f(more)h(local)e (references)i(to)f(it.)75 1619 y Ff(4.4)50 b(Performance)75 1706 y Fi(The)8 b(motivation)d(to)j(use)f(a)h(run-time)g(parser)g(to)f (generate)h(messages)f(is)h(to)f(make)h(each)g(class)g(as)f(self-contained)75 1763 y(and)i(lightweight)e(as)j(possible,)f(so)g(that)g(clients)f(and)i (servers)g(can)f(be)h(easily)f(assembled)g(from)i(a)f(class)f(library)75 1819 y(without)k(having)i(to)g(carry)h(extra)f(baggage.)29 b(This)14 b(is)h(particularly)f(attractive)h(in)g(a)g(system)g(composed)g(of) 75 1875 y(communicating)10 b(objects)g(where)i(each)f(class)g(may)h(be)f (visible)f(remotely)m(.)125 1932 y(The)k(run-time)g(parser)h(is)f(composed)g (of)h(a)g(loop)e(that)h(for)h(each)g(parameter)g(enters)f(a)h(switch)f (statement)75 1988 y(depending)8 b(on)h(the)h(type)f(of)g(the)h(parameter)m (.)17 b(Each)10 b(branch)f(of)h(the)f(switch)g(statement)g(contains)f(code)i (similar)75 2045 y(to)h(what)f(a)i(compiled)f(stub)f(would)g(contain)g(for)h (the)g(same)h(type)f(of)g(parameter)m(.)p 360 2156 1200 2 v 359 2212 2 57 v 368 2212 V 393 2196 a Fe(void)29 b(f\(int*\))13 b Fi(with)d(MiG)h(\(simple)g(server\))p 1255 2212 V 169 w(338)49 b Fb(\026)p Fi(s)p 1551 2212 V 1560 2212 V 360 2214 1200 2 v 359 2271 2 57 v 368 2271 V 393 2254 a Fe(void)29 b(f\(int*\))13 b Fi(with)d(MiG)h(\(complex)g(server\))p 1255 2271 V 50 w(490-590)49 b Fb(\026)p Fi(s)p 1551 2271 V 1560 2271 V 360 2272 1200 2 v 359 2329 2 57 v 368 2329 V 393 2312 a Fe(void)29 b(f\(int*\))13 b Fi(with)d(C++)h(package)p 1255 2329 V 298 w(596)49 b Fb(\026)p Fi(s)p 1551 2329 V 1560 2329 V 360 2330 1200 2 v 359 2387 2 57 v 368 2387 V 393 2370 a Fe(void)29 b(f\(file**\))13 b Fi(with)e(C++)g (package)p 1255 2387 V 220 w(1156)49 b Fb(\026)p Fi(s)p 1551 2387 V 1560 2387 V 360 2388 1200 2 v 75 2465 a(T)m(able)12 b(1:)19 b(Remote)13 b(invocation)d(times)j(measured)g(on)f(a)h(25MHz)f(i386)g (HP)h(V)-5 b(ectra)12 b(with)g(the)g(client)g(and)g(the)75 2522 y(server)f(on)g(the)g(same)h(machine)p eop %%Page: 11 11 bop 125 42 a Fi(T)m(able)15 b(1)h(shows)f(the)h(total)f(elapsed)h(times)g (for)g(calling)f(a)h(simple)g(C)h(function)d(returning)h(one)h(integer)n(,)75 98 y(for)f(a)g(similar)g(C++)g(virtual)e(function)h(and)h(for)g(a)g(C++)g (virtual)f(function)f(returning)h(an)h(object.)27 b(The)15 b(\256rst)75 154 y(row)d(was)g(obtained)e(with)h(a)i(trivial)d(client)i(and)f (server)i(using)d(stubs)h(generated)h(by)f(the)h(the)g(Mach)g(Interface)75 211 y(Generator)g(\(MiG\).)g(It)g(represents)f(the)g(minimum)h(time)g(it)f (takes)g(to)g(pack)h(and)f(unpack)h(the)f(parameters)h(and)75 267 y(perform)e(the)f(RPC.)h(The)g(C++)f(package)g(is)g(more)h(complex)e (since)h(each)h(invocation)d(includes)h(acquiring)g(and)75 324 y(releasing)14 b(several)h(mutexes,)g(checking)f(if)h(there)g(are)g (still)e(threads)h(available)g(to)h(service)f(other)h(requests,)75 380 y(checking)c(the)h(sequence)g(number)f(and)h(other)g(\256elds)f(in)h(the) f(incoming)g(message)h(to)g(prevent)f(races)i(relative)75 437 y(to)k(garbage-collection,)i(and)f(\256nally)f(unpacking)f(the)i(message)g (and)g(performing)g(the)f(invocation)f(\(row)75 493 y(3\).)28 b(When)14 b(similar)h(operations)e(are)j(successively)d(added)i(to)f(the)h (MiG-based)f(server)n(,)j(closer)d(values)g(are)75 550 y(obtained)d(\(row)g (2\).)19 b(The)12 b(last)f(row)h(shows)e(the)i(time)g(to)f(invoke)g(a)h (remote)g(virtual)f(function)g(that)g(returns)g(an)75 606 y(object.)26 b(The)15 b(additional)d(costs)i(in)g(this)g(case)h(are)g(the)f(callbacks)g (at)h(the)f(server)n(,)j(the)d(longer)g(time)h(it)f(takes)75 663 y(Mach)e(to)f(send)f(a)i(message)f(that)g(contains)f(a)h(port,)g(and)g (the)g(cost)g(of)g(instantiating)d(the)j(proxy)f(object.)125 719 y(These)j(values)h(show)f(that)g(the)g(performance)i(of)f(our)g(RPC)g (package)g(is)g(roughly)e(equivalent)h(to)g(a)h(MiG)75 775 y(based)d(system)g(that)g(does)g(a)g(similar)g(amount)g(of)h(work,)f(thus)f (con\256rming)i(our)f(assumption)e(that)i(the)g(cost)g(of)75 832 y(parsing)j(the)g(messages)h(at)f(run-time)h(has)f(a)h(negligible)e(ef)o (fect)i(on)f(the)h(overall)f(performance.)28 b(They)14 b(also)75 888 y(show)8 b(that)h(our)g(C++)g(remote)h(invocation)d(subsystem)h(is)h (more)h(complex)f(and)g(has)g(more)h(run-time)f(overhead)75 945 y(than)j(a)h(simple)g(RPC)g(based)g(server)n(,)h(but)e(the)g(same)i (level)e(of)h(complexity)e(and)i(overhead)f(must)h(be)g(present)75 1001 y(in)e(more)i(realistic)e(servers.)19 b(It)12 b(should)e(be)i(noted)f (that)g(these)h(measurements)g(are)h(only)e(approximate)g(in)g(the)75 1058 y(sense)g(that)f(it)h(is)g(very)g(hard)g(to)g(compare)h(systems)e(that)g (do)h(dif)o(ferent)g(things.)125 1114 y(Our)g(18)f(proxy)h(classes)f(have)h (a)g(total)f(of)h(85)g(methods)f(and)h(consume)g(about)f(70)h(Kilobytes)e(of) i(text)f(space)75 1171 y(and)f(inititalized)d(data.)16 b(A)9 b(MiG)g(\256le)g(with)f(87)h(similar)f(de\256nitions)f(produces)i(30)f (Kilobytes)f(for)i(the)g(user)o(-side)75 1227 y(stubs)h(\256le)i(and)g(63)f (Kilobytes)e(for)j(the)f(server)o(-side)h(stubs)e(\256le.)18 b(W)l(e)12 b(were)g(expecting)f(more)h(dramatic)g(space)75 1284 y(savings)h(by)h(not)g(using)g(compiled)g(stubs.)25 b(Our)15 b(proxies)e(are)j(lar)o(ger)f(than)f(we)h(expected)f(because)h(method)75 1340 y Fe(init)p 186 1340 14 2 v 17 w(class)g Fi(is)e(generally)g(very)h(lar) o(ge)f(and)h(proxy)e(classes)h(contain)g(several)g(methods)g(that)g(have)g (to)g(be)75 1396 y(present)d(in)h(all)g(classes)f(of)h(the)g(library)m(.)16 b(In)11 b(a)g(2.9K)g(proxy)m(,)f(these)h(two)f(factors)h(account)f(for)i (about)e(2K)g(of)h(the)75 1453 y(total)f(text)h(size.)16 b(W)l(e)c(never)f (made)h(any)f(ef)o(fort)h(to)e(optimize)h(these)g(values.)75 1599 y Fj(5)60 b(Related)13 b(W)m(ork)75 1702 y Fi(The)7 b(characteristics)g (of)g(our)g(system)g(forced)g(us)g(to)g(put)g(a)g(much)g(bigger)g(emphasis)g (on)g(the)g(support)g(of)g(dif)o(ferent)75 1759 y(and)k(customized)g (client-side)e(implementations)h(of)h(the)g(same)h(interface)g(than)e(most)h (of)h(the)f(previous)f(work)75 1815 y(on)g(this)g(\256eld.)16 b(This)10 b(fact)h(in\257uenced)g(heavily)e(our)i(main)g(design)e(choices.)16 b(On)11 b(the)f(other)g(hand,)h(our)g(system)75 1872 y(is)17 b(more)g(tightly)f(integrated)g(in)g(the)h(sense)g(that)g(our)g(clients)f (and)h(servers)g(are)h(system)e(entities)g(that)g(are)75 1928 y(not)f(supposed)f(to)h(be)g(coded)g(or)h(directly)e(used)h(by)g(user)h (programs.)29 b(This)14 b(allowed)h(us)g(to)g(impose)g(some)75 1984 y(restrictions)d(that)h(otherwise)g(would)f(have)i(been)g(undesirable,)f (such)h(as)f(not)g(considering)g(mixing)f(servers)75 2041 y(written)e(in)h (very)g(dif)o(ferent)g(programming)g(languages.)125 2097 y(The)j(Object)f (Request)h(Broker)h(Architecture)e(and)h(Speci\256cation)g(from)g(OMG[10])h (provides)d(a)j(frame-)75 2154 y(work)j(to)f(de\256ne)i(interfaces)e(and)h (specify)g(the)g(mechanisms)g(by)f(which)h(objects)f(can)h(interoperate)f(in) h(a)75 2210 y(heterogeneous)10 b(environment.)17 b(The)12 b(speci\256cation)e (is)i(language)f(and)g(even)h(implementation)e(independent)75 2267 y(and)i(aims)g(at)g(being)f(used)h(by)f(all)h(kinds)f(of)h (applications.)17 b(It)11 b(de\256nes)h(an)h(IDL)e(that)h(is)f(a)i(subset)e (of)h(C++)f(and)75 2323 y(supports)g(a)i(model)g(for)g(separating)e (interface)i(and)g(implementation)e(similar)i(to[9)o(].)22 b(W)l(e)13 b(could)f(have)h(used)75 2380 y(their)8 b(IDL)h(and)g(compiler)g (to)f(generate)i(our)e(abstract)h(classes)f(but)h(they)f(were)h(not)g (available)f(when)h(we)g(started)75 2436 y(the)i(project[3)o(].)125 2493 y(A)17 b(number)f(of)h(other)f(works)g(addressed)g(the)h(issue)f(of)g (distributed)f(C++)h(applications)f(by)h(proposing)75 2549 y(extensions)c(to)i(the)f(language[14)o(,)i(8)o(].)26 b(In)14 b(our)g(case)g(this)f(was)h(not)f(an)h(option.)24 b(One)14 b(of)g(our)g(requirements)75 2605 y(was)c(the)g(ability)f(to)h(compile)g(the) g(system)f(with)h(existing)e(compilers,)i(so)g(that)g(other)g(people)g(could) f(reuse)h(our)75 2662 y(work)h(and)g(we)g(could)f(not)h(af)o(ford)h(the)e(ef) o(fort)i(of)f(writing)f(our)h(own)f(C++)h(pre-processor)g(or)g(compiler)m(.)p eop %%Page: 12 12 bop 125 42 a Fi(Extended)7 b(C++[12])h(extends)g(C++)h(with)e(constructs)g (for)i(distributed)e(programming.)15 b(It)8 b(is)h(implemented)75 98 y(as)g(a)h(pre-processor)f(that)g(generates)g(standard)g(C++)g(code.)16 b(Our)10 b(goal)e(was)i(not)e(to)h(de\256ne)h(a)g(distributed)d(C++.)75 154 y(Instead,)j(we)h(focused)f(on)g(using)f(the)h(language)f(as)i(it)e(is)h (to)g(program)h(a)f(distributed)e(system.)16 b(The)10 b(features)h(in)75 211 y(the)g(language)g(that)g(are)i(inadequate)e(or)g(irrelevant)g(to)h(our)f (goals)g(were)h(simply)f(not)g(used.)17 b(This)11 b(allowed)g(us)75 267 y(to)h(ignore)g(all)g(the)g(hard)g(issues)g(about)f(handling)g(or)h (disallowing)e(certain)i(constructs)f(that)h(do)g(not)g(apply)g(to)75 324 y(the)f(distributed)e(case.)125 380 y(Several)16 b(systems)f(have)g (implemented)g(RPC)i(generators)e(for)h(C++)f([4,)h(11])g(but)e(they)i(do)f (not)g(support)75 437 y(several)c(client-side)f(implementations)f(for)j(the)e (same)i(interface.)125 493 y(The)i(SOS)h(project[13)o(])g(introduced)e(the)h (notion)f(of)h(proxies)g(and)g(provided)g(one)g(of)g(the)h(earlier)f(imple-) 75 550 y(mentations)c(of)h(a)h(system)e(composed)h(of)g(a)h(number)f(of)g (communicating)f(C++)h(objects.)125 606 y(Choices[7)o(])g(is)e(another)h (operating)f(system)g(written)g(in)h(C++.)16 b(It)10 b(provides)f(a)h (library)f(of)i(C++)e(classes)h(that)75 663 y(may)j(be)g(customized)f(to)g (construct)f(dif)o(ferent)i(instances)e(of)i(an)f(operating)g(system.)20 b(However)n(,)13 b(Choices)g(is)75 719 y(from)e(the)e(C++)h(point)f(of)h (view)g(a)g(monolithic)f(application,)f(i.e.)17 b(it)10 b(lives)f(all)g(in)h (the)g(same)h(address)e(space,)i(not)75 775 y(addressing)f(the)h(issues)f(of) h(client-server)f(interaction.)75 921 y Fj(6)60 b(Retr)o(ospective)75 1025 y Fi(This)12 b(section)h(evaluates)f(the)h(use)h(of)f(C++)g(in)g(our)g (project)g(and)g(some)g(of)h(the)f(design)f(decisions)g(presented)75 1081 y(earlier)m(.)75 1205 y Ff(6.1)50 b(Using)12 b(C++)75 1292 y Fi(The)f(Mach)g(3)g(multi-server)f(was)g(initially)f(written)g(in)i (MachObjects[6)o(],)g(an)g(object-oriented)e(environment)75 1349 y(based)g(on)g(C)h(macros)h(and)e(library)g(routines)f(that)h(provides)f (a)i(programming)f(model)h(similar)f(to)g(Objective-C)75 1405 y(with)h(some)h(extensions.)k(A)c(lar)o(ge)g(amount)g(of)g(BSD)h(Unix)e(C)h (code)g(is)g(also)f(reused)h(with)f(minimal)h(changes.)125 1462 y(The)19 b(decision)g(to)g(use)g(C++)h(instead)e(of)i(MachObjects)f(was) g(mostly)g(motivated)g(by)g(the)g(perceived)75 1518 y(need)12 b(to)g(use)g(a)g(well-known)e(language)i(instead)f(of)h(an)g(arcane)h(and)f (virtually)e(unknown)h(environment)g(like)75 1575 y(MachObjects.)125 1631 y(Our)j(major)h(concerns)f(with)f(using)g(C++)h(were)h(the)f(adequacy)g (of)g(static)g(type)f(checking)h(in)g(a)g(dynamic)75 1688 y(system)d(such)f (as)i(ours)e(and)h(the)g(impact)g(of)g(having)f(to)h(use)g(a)h(dif)o(ferent)f (compiler)m(.)125 1744 y(The)c(\256rst)g(problem)g(was)g(adequately)g(add)o (ressed)g(wi)o(th)f(our)h(model)f(for)h(specify)o(ing)f(int)o(erfaces)h(and)g (derivin)o(g)75 1801 y(the)15 b(implementation)f(classes)h(and)g(the)g (additional)e(mechanism)j(for)f(run-time)h(pointer)e(conversion.)28 b(W)l(e)75 1857 y(think)13 b(that)g(one)h(of)g(the)g(most)g(positive)e (aspects)i(of)g(using)f(C++)h(was)g(the)g(better)f(expressiveness)g(of)h (typed)75 1913 y(interfaces)d(and)g(the)g(type-checking)f(provided)g(by)h (the)f(compiler)m(.)125 1970 y(The)h(biggest)f(challenge)h(was)h(the)f(level) g(of)h(stability)d(and)j(maturity)f(of)g(the)h(GNU)f(C++)h(tools)e (\(compiler)n(,)75 2026 y(debugger)n(,)g(linker\))g(and)g(their)g (integration)e(with)i(our)g(build)f(environment.)15 b(This)9 b(is)h(only)f(a)i(small)f(part)g(of)g(the)75 2083 y(bigger)h(problem)g(of)h (introducing)d(a)j(new)f(compiler)g(in)g(an)h(existing)e(or)o(ganization.)16 b(W)l(e)c(experienced)f(many)75 2139 y(problems)f(with)g(poor)g(or)g(no)h (support)e(for)i(virtual)e(base)i(classes)f(and)g(multiple-inheritance)f(in)h (the)g(compiler)75 2196 y(and)j(debugger)m(.)24 b(Some)15 b(of)e(these)h (problems)f(have)g(been)h(overcome)g(with)e(more)j(recent)f(versions)e(of)i (these)75 2252 y(tools;)9 b(others)i(have)g(not.)75 2376 y Ff(6.2)50 b(C++)13 b(vs.)19 b(an)12 b(Interface)g(De\256nition)f(Language)75 2463 y Fi(One)e(of)g(the)g(uncommon)g(characteristics)g(of)g(this)f(system)h (is)f(that)h(it)g(does)f(not)h(use)g(an)g(IDL)g(and)g(instead)g(relies)75 2520 y(only)h(on)h(C++)g(to)g(de\256ne)g(RPCs.)125 2576 y(There)f(are)g(two)f (layers)g(at)g(which)g(we)h(could)f(have)g(used)g(an)h(IDL:)f(the)g(service)h (layer)f(where)h(interfaces)f(are)75 2633 y(speci\256ed)k(in)f(terms)h(of)g (classes)g(and)f(objects,)h(and)g(the)g(RPC)h(layer)f(where)g(we)g(de\256ne)g (the)g(messages)g(to)f(be)p eop %%Page: 13 13 bop 75 42 a Fi(interchanged.)20 b(In)13 b(simple)g(systems)f(there)g(is)h(a)g (one-to-one)f(correspondence)g(between)g(these)h(two)f(layers,)75 98 y(but)e(in)h(more)h(complicated)e(ones)h(like)g(ours)f(that)h(is)g(not)f (necessarily)g(the)h(case.)125 154 y(At)17 b(the)g(service)h(layer)f(our)g (solution)f(is)h(basically)f(to)h(coalesce)g(the)h(IDL)f(and)g(C++)h(by)f (de\256ning)f(the)75 211 y(interfaces)e(using)g(the)g(subset)f(of)i(C++)f (that)g(\252makes)h(sense\272.)27 b(The)14 b(main)h(drawback)f(of)h(this)e (approach)i(is)75 267 y(that)g(we)h(have)g(no)g(way)f(to)h(automatically)e (check)i(the)g(constructs)e(allowed)h(by)h(C++)g(that)f(are)h(invalid)f(in)75 324 y(the)e(distributed)e(case)j(\(e.g.)25 b(pointers,)13 b(public)f(data\).) 24 b(That)13 b(task)g(is)g(left)g(to)g(the)h(programmer)n(,)h(who)e(has)h(to) 75 380 y(carefully)g(design)f(these)g(abstract)h(classes)f(using)g(only)g(a)h (small)g(subset)f(of)h(the)g(language.)24 b(In)14 b(our)g(system)75 437 y(these)e(interfaces)g(are)h(a)g(crucial)g(part)f(of)g(the)h(design)e (and)h(their)g(de\256nition)f(involved)g(discussions)f(between)75 493 y(several)j(people)f(of)i(dif)o(ferent)f(groups,)f(which)h(minimized)g (the)f(number)i(of)f(mistakes)f(made)i(by)f(misuse)f(of)75 550 y(the)f(language.)125 606 y(De\256ning)g(the)h(service)h(interfaces)f (with)f(an)i(object-oriented)d(IDL)i(and)h(from)f(there)h(directly)e (generating)75 663 y(the)i(C++)f(implementation)g(classes)g(does)h(not)f (support)f(the)i(notion)e(of)i(multiple)f(implementations)f(for)i(the)75 719 y(same)h(interface.)22 b(Since)14 b(there)f(are)h(no)e(C++)h(classes)g (that)f(describe)h(the)g(interface,)h(clients)e(have)h(to)g(de\256ne)75 775 y(variables)d(of)g(the)g(C++)g(implementation)f(types)g(generated)h(by)g (the)g(IDL)g(compiler)n(,)h(which)f(defeats)g(our)g(goal)75 832 y(of)h(supporting)e(dif)o(ferent)i(proxies)f(for)i(the)f(same)g (interface.)125 888 y(W)l(e)g(could)f(have)h(used)g(an)g(object-oriented)e (IDL)i(to)f(automatically)g(generate)h(the)f(C++)h(abstract)f(classes,)75 945 y(instead)j(of)g(writing)g(them)g(manually)h(as)f(we)h(did)f(\(if)h(such) f(IDL)h(and)f(compiler)h(were)g(available)f(to)g(us\).)24 b(A)75 1001 y(hierarchy)12 b(of)g(interface)h(classes)f(would)f(be)h(de\256ned)g(in) g(IDL)g(and)h(the)f(IDL)g(compiler)g(would)f(generate)h(our)75 1058 y(hierarchy)k(of)g(C++)g(abstract)g(classes.)31 b(One)16 b(of)g(the)g(drawbacks)f(of)h(this)f(approach)h(is)g(that)g(it)f(forces)h (the)75 1114 y(designer)e(of)h(the)f(system)g(to)g(de\256ne)h(the)g (interfaces)f(in)g(one)h(language)f(but)g(then)g(use)g(the)h(code)f (generated)75 1171 y(by)f(the)g(IDL)h(compiler)f(to)g(write)g(the)g (implementations.)22 b(It)14 b(might)e(also)h(be)h(hard)f(to)g(establish)f(a) i(mapping)75 1227 y(between)d(the)g(subtyping)e(rules)i(of)g(the)g(IDL)g(and) h(those)e(of)h(C++.)17 b(It)12 b(has)f(the)g(advantage)g(of)g(having)f(the)h (IDL)75 1284 y(compiler)g(checking)g(constructs)f(that)g(make)i(no)f(sense)g (in)g(the)g(distributed)e(case)j(and)f(being)g(more)h(language)75 1340 y(independent,)e(provided)g(that)g(the)h(IDL)g(compiler)g(can)h (generate)f(more)h(than)f(one)g(tar)o(get)g(language.)125 1396 y(At)i(the)g(RPC)i(level)e(we)h(require)f(the)h(programmer)g(to)f(specify)g (the)h(interfaces)f(using)f(macros)i(basically)75 1453 y(because)9 b(it)f(was)g(relatively)g(easy)g(to)g(implement)g(and)h(allowed)e(us)i(to)f (experiment)g(with)g(the)g(run-time)g(parsing)75 1509 y(of)j(messages,)h(but) e(this)g(is)h(clearly)g(unacceptable)f(as)i(a)f(general)g(solution.)125 1566 y(A)f(better)h(solution)d(would)h(be)i(to)f(have)g(an)h(RPC)g(compiler)g (that)f(automatically)f(generates)h(the)g(necessary)75 1622 y(routines)k(and)h(data)g(structures.)28 b(Using)14 b(C++)h(to)g(specify)g (the)g(interfaces,)i(as)e(we)h(did,)g(keeps)f(the)g(system)75 1679 y(very)i(homogeneous,)h(but)f(it)g(is)g(impossible)e(to)i(specify)g(all) g(the)g(dif)o(ferent)g(parameter)h(attributes)e(of)h(the)75 1735 y(communication)10 b(subsystem,)g(such)h(as)g(in-line)f(or)h (out-of-line)f(data)g(and)h(port)g(manipulation)e(supported)h(by)75 1792 y(Mach)i(IPC.)g(A)f(specialized)f(IDL)h(adequately)g(addresses)f(these)h (problems,)g(at)g(the)g(expense)f(of)h(introducing)75 1848 y(yet)g(another)g(language)f(the)h(programmer)h(has)f(to)g(deal)g(with.)125 1905 y(The)i(issue)f(of)g(interfacing)g(clients)g(and)h(servers)g(written)f (in)g(dif)o(ferent)h(languages)f(can)h(be)g(solved)f(at)g(the)75 1961 y(message)e(level)g(by)f(using)g(the)h(same)g(RPC)h(package)f(on)g(both) f(sides)g(and)h(de\256ning)f(RPCs)i(that)e(are)i(bit-for)o(-bit)75 2017 y(compatible.)24 b(At)13 b(a)h(certain)g(point)e(of)i(our)g(development) e(a)j(\256leserver)f(still)e(written)h(in)g(MachObjects)g(was)75 2074 y(perfectly)8 b(able)g(to)g(communicate)g(with)f(C++)h(clients)f(using)g (the)h(complex)f(mapped)i(\256les)f(proxy)m(,)g(just)f(because)75 2130 y(the)k(RPCs)h(between)f(them)g(had)g(remained)g(unchanged)g(when)g(the) f(clients)g(were)i(converted)f(to)f(C++.)75 2276 y Fj(7)60 b(Conclusions)75 2380 y Fi(W)l(e)17 b(present)g(a)g(model)f(to)h(write)f(a)h (client-server)g(application)e(in)h(C++)g(that)h(uses)f(C++)g(abstract)h (classes)75 2436 y(to)d(specify)g(the)g(interfaces)g(and)g(multiple)f (inheritance)h(to)g(construct)f(the)h(implementations.)24 b(This)13 b(model)75 2493 y(cleanly)f(supports)e(dif)o(ferent)i(client-side)f(and)h (server)o(-side)g(implementations)f(of)h(the)g(same)h(interface.)20 b(The)75 2549 y(lattice)13 b(of)g(interface)h(classes,)g(composed)f(of)g(C++) g(abstract)g(classes)g(using)f(mostly)h(single)f(inheritance,)i(is)75 2605 y(visible)c(to)g(both)g(clients)h(and)g(servers)g(and)g(guarantees)f (the)h(consistency)f(of)h(the)g(implementations.)p eop %%Page: 14 14 bop 125 42 a Fi(W)l(e)15 b(believe)f(that)g(the)g(model)g(presented)g(here)h (to)f(de\256ne)g(the)g(interfaces)h(and)f(to)g(construct)f(the)h(imple-)75 98 y(mentations)c(is)g(a)i(good)e(way)h(to)f(write)h(client-server)g (applications)d(in)j(C++)g(and)g(can)g(be)g(widely)f(used)h(in)f(the)75 154 y(C++)h(community)m(.)75 300 y Fj(8)60 b(Acknowledgements)75 404 y Fi(Many)15 b(people)f(at)h(CMU)h(and)e(at)h(the)g(Research)g(Institute) e(of)i(OSF)g(have)g(participated)f(in)g(the)h(design)e(and)75 460 y(implementation)8 b(of)i(the)g(system.)15 b(Beside)10 b(the)f(authors,)h(they)f(are:)16 b(J.)10 b(Mark)g(Stevenson,)g(Jonathan)f (J.)h(Chew)m(,)75 517 y(Paul)18 b(Neves,)i(Paul)e(Roy)m(,)i(Robert)e(Baron,)i (Alessandro)d(Forin,)i(Jef)o(frey)g(Heller)n(,)h(Michael)e(Jones,)h(Keith)75 573 y(Loepere,)f(Douglas)e(Orr)n(,)j(Richard)d(Rashid,)i(Franklin)e(Reynolds) g(and)g(Richard)h(Sanzi.)33 b(John)16 b(LoV)-5 b(erso,)75 630 y(Franklin)10 b(Reynolds)g(and)h(the)g(anonymous)e(reviewers)i(provided)f (helpful)g(comments)h(on)f(early)h(versions)f(of)75 686 y(this)g(paper)m(.)75 826 y Fj(Refer)o(ences)96 918 y Fa([1])22 b(Richard)10 b(P)-5 b(.)12 b(Draves.)k(A)11 b(Revised)g(IPC)f(Interface.)17 b(In)10 b Fk(Proceedings)h(of)g(Mach)f(Usenix)h(Workshop)p Fa(,)g(Burlington,)167 968 y(V)-5 b(ermont,)11 b(October)f(4-5)f(1990.)96 1043 y([2])22 b(K.)12 b(Gorlen,)h(S.)f(Orlow)m(,)g(and)g(P)-5 b(.)13 b(Plexico.)20 b Fk(Data)12 b(Abstraction)f(and)i(Object-Oriented)f(Programming)g(in)g(C++)p Fa(.)167 1093 y(John)e(W)n(iley)g(&)h(Sons,)f(1990.)96 1167 y([3])22 b(P)-5 b(.)16 b(Guedes.)29 b(Use)15 b(of)g(Object-Oriented)f (Technology)h(in)f(the)h(Implementation)f(of)h(a)h(Distributed)d(Operating) 167 1217 y(System.)19 b(In)11 b Fk(Addendum)h(to)g(the)g(Proceedings)g(of)g (OOPSLA/ECOOP)p Fa(,)g(Ottawa,)h(Canada,)f(Oct)g(1990.)f(Sigplan)167 1267 y(Notices)f(Special)h(Issue.)96 1342 y([4])22 b(J.)12 b(Heliotis)e(and)h(P)-5 b(.)13 b(Mansey)m(.)19 b(Remote)11 b(Object)h(Invocation)e(and)h(its)g(Implementation)f(in)h(C++.)19 b(In)11 b Fk(Proc.)i(C++)167 1392 y(at)d(Work)p Fa(,)g(C++)h(Report)e(and)i (the)f(W)m(ang)g(Institute)f(of)h(Boston)f(University)m(,)g(1989.)96 1466 y([5])22 b(D.)9 b(Julin,)g(J.)h(Chew)m(,)g(P)-5 b(.)10 b(Guedes,)g(P)-5 b(.)10 b(Neves,)h(P)-5 b(.)10 b(Roy)m(,)f(and)g(M.)h (Stevenson.)j(Generalized)d(Emulation)e(Services)i(for)167 1516 y(Mach)i(3.0)g(-)f(Overview)m(,)h(Experiences)h(and)f(Current)e(Status.) 18 b(In)12 b Fk(Proceedings)g(of)g(Usenix)h(Mach)f(Symposium)p Fa(,)167 1566 y(Monterey)m(,)e(CA,)h(Nov)f(20-22)f(1991.)96 1641 y([6])22 b(D.)13 b(Julin)e(and)h(R.)h(Rashid.)19 b(Machobjects.)i(T)m (echnical)13 b(report,)g(Mach)g(Project,)g(Carnegie)f(Mellon)f(University)m (,)167 1690 y(1989.)96 1765 y([7])22 b(P)-5 b(.)12 b(Madany)m(,)h(D.)f (Leyens,)h(and)e(V)-5 b(.)12 b(Russo.)18 b(A)12 b(C++)g(Class)f(Hierarchy)h (for)f(Building)e(UNIX-like)h(File)h(Systems.)167 1815 y(In)f Fk(Proc.)h(1988)f(Usenix)g(C++)g(Conference)p Fa(,)i(Denver)n(,)f(CO)f (\(USA\),)g(Oct)h(1988.)96 1890 y([8])22 b(Jos)r(\302)-16 b(e)7 b(Alves)g(Marques)g(and)g(Paulo)g(Guedes.)j(Extending)5 b(the)i(Operating)f (System)h(to)g(Support)e(an)i(Object-Oriented)167 1940 y(Environment.)14 b(In)c Fk(Proceedings)h(of)e(OOPSLA)i(89)p Fa(,)g(New)f(Orleans,)h(2-6th)e (October)h(1989.)96 2014 y([9])22 b(B.)15 b(Martin.)27 b(The)16 b(Separation)f(of)f(Interface)i(and)f(Implementation)f(in)h(C++.)28 b(In)15 b Fk(Proc.)k(1991)d(Usenix)i(C++)167 2064 y(Conference)p Fa(,)11 b(W)m(ashington,)e(DC)h(\(USA\),)h(Apr)e(1991.)75 2139 y([10])22 b(OMG.)f(The)13 b(common)g(object)f(request)g(broker:)19 b(Architecture)12 b(and)g(speci\256cation.)21 b(T)m(echnical)14 b(Report)d(OMG)167 2189 y(Document)f(Number)h(91.12.1,)f(Revision)f(1.1,)i (Object)f(Management)h(Group,)e(December)j(1991.)75 2263 y([11])22 b(G.)15 b(Parrington.)26 b(Reliable)15 b(Distributed)e(Programming)h(in)h (C++:)24 b(The)16 b(Arjuna)e(Approach.)28 b(In)14 b Fk(Proc.)19 b(1990)167 2313 y(Usenix)11 b(C++)f(Conference)p Fa(,)h(San)f(Francisco,)i (CA)e(\(USA\),)g(Apr)g(1990.)75 2388 y([12])22 b(Robert)11 b(Seliger)n(.)19 b(Extended)12 b(C++.)20 b(In)12 b Fk(Proc.)i(1990)e(Usenix)h (C++)f(Conference)p Fa(,)i(San)e(Francisco,)h(CA)f(\(USA\),)167 2438 y(Apr)e(1990.)75 2512 y([13])22 b(Marc)15 b(Shapiro.)24 b(Structure)13 b(and)i(Encapsulation)e(in)g(Distributed)f(Systems:)23 b(The)15 b(Proxy)e(Principle.)24 b(In)14 b Fk(Pro-)167 2562 y(ceedings)j(of)g(the)g(6th.)g(International)d(Conference)k(on)f(Distributed) e(Computer)i(Systems)p Fa(,)g(pages)e(198\261204,)167 2612 y(Cambridge,)10 b(Mass.)i(\(USA\),)e(May)g(1986.)g(IEEE.)p eop %%Page: 15 15 bop 75 42 a Fa([14])22 b(M.)c(T)o(ieman.)36 b(W)n(rappers:)31 b(Solving)16 b(the)h(RPC)h(Problem)g(in)f(GNU)h(C++.)36 b(In)17 b Fk(Proc.)23 b(1988)e(Usenix)h(C++)167 91 y(Conference)p Fa(,)11 b(Denver)n(,)g(CO)f(\(USA\),)h(Oct)f(1988.)75 166 y([15])22 b(Jim)9 b(W)m(aldo.)i(Controversy:)h(The)e(Case)f(for)f(Multiple)f (Inheritance)h(in)h(C++.)k Fk(Computing)6 b(Systems)p Fa(,)k(4\(2\),)e (Spring)167 216 y(1991.)p eop %%Trailer end userdict /end-hook known{end-hook}if %%EOF