1 /*
2 
3     This file is part of the Maude 2 interpreter.
4 
5     Copyright 1997-2003 SRI International, Menlo Park, CA 94025, USA.
6 
7     This program is free software; you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation; either version 2 of the License, or
10     (at your option) any later version.
11 
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.
16 
17     You should have received a copy of the GNU General Public License
18     along with this program; if not, write to the Free Software
19     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
20 
21 */
22 
23 //
24 //      Class for socket manager symbols.
25 //
26 #ifndef _socketManagerSymbol_hh_
27 #define _socketManagerSymbol_hh_
28 #include <map>
29 #include "externalObjectManagerSymbol.hh"
30 #include "pseudoThread.hh"
31 #include "dagRoot.hh"
32 
33 class SocketManagerSymbol
34   : public ExternalObjectManagerSymbol,
35     public PseudoThread
36 {
37   NO_COPYING(SocketManagerSymbol);
38 
39 public:
40   SocketManagerSymbol(int id);
41 
42   bool attachData(const Vector<Sort*>& opDeclaration,
43 		  const char* purpose,
44 		  const Vector<const char*>& data);
45   bool attachSymbol(const char* purpose, Symbol* symbol);
46   void copyAttachments(Symbol* original, SymbolMap* map);
47   void getDataAttachments(const Vector<Sort*>& opDeclaration,
48 			  Vector<const char*>& purposes,
49 			  Vector<Vector<const char*> >& data);
50   void getSymbolAttachments(Vector<const char*>& purposes,
51 			    Vector<Symbol*>& symbols);
52   //
53   //	Overridden methods from ExternalObjectManagerSymbol.
54   //
55   bool handleManagerMessage(DagNode* message, ObjectSystemRewritingContext& context);
56   bool handleMessage(DagNode* message, ObjectSystemRewritingContext& context);
57   void cleanUp(DagNode* objectId);
58   //
59   //	Overridden methods from PseudoThread.
60   //
61   void doRead(int fd);
62   void doWrite(int fd);
63   void doError(int fd);
64   void doHungUp(int fd);
65 
66 private:
67   enum Sizes
68     {
69       READ_BUFFER_SIZE = 4096
70     };
71 
72   enum SocketState
73     {
74       NOMINAL = 0,
75       WAITING_TO_CONNECT= 1,
76       WAITING_TO_READ = 2,
77       WAITING_TO_WRITE = 4,
78       LISTENING = 8,
79       WAITING_TO_ACCEPT = 16
80     };
81 
82   struct ActiveSocket
83   {
84     ActiveSocket();
85     ~ActiveSocket();
86 
87     int state;
88     //
89     //	If we are in a waiting state, we need to keep pointers to the last message
90     //	and the original rewriting context so that we can handle an asynchronous response from
91     //	the operating system.
92     //
93     DagRoot lastMessage;  // must be protected from GC
94     //
95     //	Since destruction of the context causes a cleanUp() call for each registered external
96     //	object, this should not become a dangling pointer.
97     //
98     ObjectSystemRewritingContext* originalContext;
99     //
100     //	Outgoing text.
101     //
102     //crope text;
103     char* textArray;
104     const char* unsent;
105     Rope::size_type nrUnsent;
106   };
107 
108   typedef map<int, ActiveSocket> SocketMap;
109 
110   bool getPort(DagNode* protocolArg, int& protocol);
111   bool getActiveSocket(DagNode* socketArg, int& socketId, ActiveSocket*& asp);
112   bool getText(DagNode* textArg, Rope& text);
113   bool setNonblockingFlag(int fd, FreeDagNode* message, ObjectSystemRewritingContext& context);
114 
115   void errorReply(const char* errorMessage,
116 		  FreeDagNode* orignalMessage,
117 		  ObjectSystemRewritingContext& context);
118   void createdSocketReply(int fd,
119 			  FreeDagNode* originalMessage,
120 			  ObjectSystemRewritingContext& context);
121   void acceptedClientReply(const char* addr,
122 			   int fd,
123 			   FreeDagNode* originalMessage,
124 			   ObjectSystemRewritingContext& context);
125   void sentMsgReply(FreeDagNode* originalMessage,
126 		    ObjectSystemRewritingContext& context);
127   void receivedMsgReply(char buffer[],
128 			ssize_t length,
129 			FreeDagNode* originalMessage,
130 			ObjectSystemRewritingContext& context);
131   void closedSocketReply(int socketId,
132 			 const char* errorMessage,
133 			 FreeDagNode* originalMessage,
134 			 ObjectSystemRewritingContext& context);
135 
136   bool createClientTcpSocket(FreeDagNode* message, ObjectSystemRewritingContext& context);
137   bool createServerTcpSocket(FreeDagNode* message, ObjectSystemRewritingContext& context);
138   bool acceptClient(FreeDagNode* message, ObjectSystemRewritingContext& context);
139   bool send(FreeDagNode* message, ObjectSystemRewritingContext& context);
140   bool receive(FreeDagNode* message, ObjectSystemRewritingContext& context);
141   bool closeSocket(FreeDagNode* message, ObjectSystemRewritingContext& context);
142   //
143   //	Socket subsystem signature (generated by macro expansion).
144   //
145 #define MACRO(SymbolName, SymbolClass, NrArgs) \
146   SymbolClass* SymbolName;
147 #include "socketSignature.cc"
148 #undef MACRO
149 
150   SocketMap activeSockets;
151 };
152 
153 #endif
154