This file is indexed.

/usr/include/gnelib/SyncConnection.h is in libgnelib-dev 0.75+svn20091130-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
#ifndef SYNCCONNECTION_H_INCLUDED_C43C0621
#define SYNCCONNECTION_H_INCLUDED_C43C0621

/* GNE - Game Networking Engine, a portable multithreaded networking library.
 * Copyright (C) 2001-2006 Jason Winnebeck 
 * Project website: http://www.gillius.org/gne/
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <gnelib/Error.h>
#include <gnelib/ConnectionListener.h>
#include <gnelib/ConditionVariable.h>
#include <gnelib/Mutex.h>

namespace GNE {
class Address;
class Connection;
class Packet;
class ClientConnection;
class ServerConnection;
class ConnectionParams;

/**
 * @ingroup midlevel
 *
 * A class for performing synchronous connections.  All methods of this class
 * except writing block until completion.  This is useful while
 * connecting or performing trivial connections/communications.  Many times
 * if you want to perform non-game transfers, for example a server-query
 * connection or another simple service it might be simpler to spawn a new
 * thread and run the SyncConnection while the rest of the program runs.
 *
 * SyncConnections throw an Error class on an error, so you must use
 * try/catch blocks.  Note that the Error class can't describe everything
 * about an error, so sometimes more specific information is available in the
 * debug logs (enable them with GNE::initDebug).
 *
 * All transfers with SyncConnection are reliable (using TCP, SPX, or similar
 * protocol).
 *
 * If an error occurs, the connection was terminated.  The underlying
 * connection is disconnected, and this SyncConnection becomes released.
 *
 * When you wrap a Connection with this class, the event listener for that
 * Connection is suspended and SyncConnection "takes over" until it is
 * release()d.  So while in synchronous mode you will receive no events
 * through your asynchronous event listener, with the exception of
 * onDisconnect and onConnect.  It is best only to use SyncConnection
 * while connecting, because of possible side-effects when you
 * wrap the Connection.  If there was already data pending that you did not
 * receive in asynchronous mode -- it was not lost, but you will get it from
 * the next packet read.  If you start out with a SyncConnection, then you
 * can be certain no unexpected packets will be arriving.
 *
 * See the example exsynchello for more help with the usage of this class.
 */
class SyncConnection : public ConnectionListener {
public: //typedefs
  typedef SmartPtr<SyncConnection> sptr;
  typedef WeakPtr<SyncConnection> wptr;

private: //ctor is private because of member thisPtr
  /**
   * @see create
   */
  SyncConnection( const SmartPtr<Connection>& target );

public:
  /**
   * Creates a new SyncConnection.  Pass in the Connection that you want to
   * wrap.  See the details above for more information.
   */
  static sptr create( const SmartPtr<Connection>& target );

  /**
   * Destructs this SyncConnection, calling release() if necessary.  If
   * releasing would throw an Error, it is ignored.  If you wish to capture
   * all errors, you should call release yourself.
   *
   * @see release()
   */
  virtual ~SyncConnection();

  /**
   * Returns the underlying Connection.
   */
  SmartPtr<Connection> getConnection() const;
  
  /**
   * Just like ClientConnection::open, this will open the port, ready for
   * connection.  If the open failed, an Error is thrown.
   *
   * It is important that the wrapped Connection is a ClientConnection, 
   * otherwise undefined behavior (likely a crash) will result.
   *
   * @throw Error if the connection could not be opened.
   */
  void open(const Address& dest, const ConnectionParams& params);
  
  /**
   * Attempts to connect to the remote side, and waits for the connection to
   * complete, throwing an Error if it was unsuccessful.  Your event listener
   * will receive the onConnect event resulting from this -- it is not
   * repressed just like onDisconnect is not repressed.  Many times though,
   * when using this method you won't have a need for onConnect, but if you
   * do create one, connect will wait until onConnect is finished.
   *
   * It is important that the wrapped Connection is a ClientConnection, 
   * otherwise undefined behavior (likely a crash) will result.
   *
   * @throw Error if the connection failed.
   */
  void connect();
  
  /**
   * Disconnects the underlying Connection.  It is best to use this function
   * instead of getConnection()->disconnect() because this will make sure
   * any pending writes will have completed through a call to release().
   *
   * @throw Error if release throws an error, or if the disconnection was
   *              unsuccessful.
   */
  void disconnect();

  /**
   * Releases this SyncConnection, returning the underlying Connection to its
   * previous event handler.  Once a SyncConnection has been released, then
   * it is essentially in an invalid state and should not be used anymore
   * (with the exception of the dtor, getConnection(), isReleased(), and
   * this function).  This function throws an Error if some underlying
   * pending operations failed since the last call on this SyncConnection.
   *
   * If release is called when the SyncConnection is already released, no
   * errors will be thrown.
   *
   * onReceive will be called in the original listener after release if
   * necessary, and onDoneWriting will be called after release if any data
   * since writing packets.
   *
   * @throw Error if an error has occurred since the last operation on this
   *              SyncConnection instance.
   */
  void release();
  
  /**
   * Returns true if release() has been called on this SyncConnection, and it
   * is not a valid object to use anymore.
   */
  bool isReleased() const;
  
  /**
   * Reads a packet from the connection.  You should provide an already
   * allocated packet whose Packet::readPacket function will be called.
   * There will be type checking performed before this call to make sure the
   * right packet is being read.  If there is a mismatch, an error is thrown.
   * The passed packet is untouched, and the connection remains connected;
   * however, the data just received (the incorrect packet) is lost.
   * The connection will remain connected in this case.
   *
   * @throw PacketTypeMismatch if the read packet was of the wrong type.
   * @throw Error if an error occurred while reading, or an error occurred
   *              since the last interaction with this object.
   */
  SyncConnection& operator >> (Packet& packet);
  
  /**
   * Writes a Packet to the connection by placing it in the outgoing queue.
   * This method actually doesn't block like every other SyncConnection
   * method, but on a write there is no reason to block, since it will not
   * effect the logic of the code.  This allows for packet caching to improve
   * network performance, and allows you to perform reads while the
   * connection is still writing.  All of this is transparent to your logic,
   * though.  release() will block until all writes are completed, and the
   * destructor and disconnect() function call release() if needed.
   *
   * A SyncConnection should be released or destroyed before the start of
   * %GNE shutdown if you want to guarantee all packet sends were attempted.
   *
   * @throw Error if an error occurred while writing, or an error occurred
   *              since the last interaction with this object.
   */
  SyncConnection& operator << (const Packet& packet);
  
private:
  /**
   * Not for use for the end-user API.  During connection, events need to be
   * treated a little differently, as well as releasing, because onNewConn or
   * onConnect may not have been called or are still processing, and we don't
   * want to release.  This is used only by the GNE protocol connecting code,
   * and is used there to help guarantee that onNewConn/onConnect is the
   * first event, and onDisconnect the last if onNewConn/onConnect ever
   * finished.  Basically this "delays" the release of this SyncConnection.
   *
   * This must be called BEFORE any events can possibly be received (so
   * before registration into ConnectionEventGenerator).
   */
  void startConnect();

  /**
   * Complement function with startConnect, this must be called if
   * startConnect was called.  Pass true to passEvents if the connection was
   * successful and onFailure and onDisconnect should be passed onto the old
   * listener.
   *
   * Pass false if the connection failed and the events should be discarded
   * and not passed on.  If false was passed, the listener for the connection
   * was set to ConnectionListener::getNullListener() to discard the events.
   * If false is passed, and release throws an Error, it is not passed
   * through.
   *
   * @throw Error if release throws.
   */
  void endConnect(bool passEvents);

  //Make friends so they can use startConnect and endConnect.
  friend class ServerConnection;
  friend class ClientConnection;
  
  /**
   * The actual releasing functionality, but in a separate function so that
   * calling functions can manipulate the mutexes, which are not necessarily
   * recursive.
   *
   * @throw Error if an error occurred while releasing, or an error occurred
   *              since the last interaction with this object.
   */
  void doRelease();

  /**
   * The event listeners for SyncConnection that will override the current
   * listener our connection has.
   */
  virtual void onConnect(SyncConnection&);
  virtual void onConnectFailure(Connection&, const Error&);
  virtual void onNewConn(SyncConnection&);
  virtual void onDisconnect( Connection& );
  virtual void onExit( Connection& );
  virtual void onError( Connection&, const Error&);
  virtual void onFailure( Connection&, const Error&);
  virtual void onReceive( Connection& );

  /**
   * A ConditionVariable we can wait on to wait for incoming data.
   * This is also used as a mutex for errors, as waiting for incoming data
   * is also sensitive to if an error happens -- it will stop waiting if the
   * connection failed.
   */
  ConditionVariable recvNotify;

  /**
   * Checks to see if an error has occurred, and if so, throws it.
   *
   * @throw Error if an error has occurred.
   */
  void checkError();

  /**
   * Sets the error.
   */
  void setError(const Error& error);

  /**
   * Weak pointer to this, set in create.
   */
  wptr thisPtr;

  /**
   * Synchronization for release and connecting events.
   */
  Mutex sync;

  /**
   * The current error state of this connection.  Error::NoError if there is
   * no error.  recvNotify acts to keep this variable from being accessed by
   * multiple threads.
   */
  Error currError;

  /**
   * The underlying Connection.
   */
  SmartPtr<Connection> conn;

  /**
   * The old listener for asynchronous communications that the Connection just
   * had.  If this is NULL, then this object has been released.
   */
  SmartPtr<ConnectionListener> oldListener;

  volatile bool released;

  /**
   * @see setConnectMode
   */
  volatile bool connectMode;
};

} // namespace GNE

#endif /* SYNCCONNECTION_H_INCLUDED_C43C0621 */