Project

General

Profile

Revision 642

Added by Jason knichel about 16 years ago

added more comments

View differences:

ConnectionPool.cpp
22 22

  
23 23
/**
24 24
 * @brief The default constructor for ConnectionPool
25
 *
26
 * @param cs The colonet server instance to use with this class
25 27
 */
26 28
ConnectionPool::ConnectionPool(ColonetServer* cs) {
27 29
  colonet_server = cs;
......
67 69
    max_file_descriptor = client_file_descriptor;
68 70
  }
69 71

  
72
	//add the new file descriptor to the set of ready descriptors
70 73
  FD_SET(client_file_descriptor, &ready_set);
71 74

  
72 75
  int next_slot = next_available_slot;
73 76

  
77
	//put the new client into the connection pool
74 78
  client_file_descriptor_array[next_slot] = client_file_descriptor;
75 79
  read_buffer[next_slot] = (char*) malloc(sizeof(char) * READ_BUFFER_SIZE);
76 80
  if (!(read_buffer[next_slot])) {
77 81
    return ERROR_ALLOCATING_MEMORY;
78 82
  }
79 83
  read_buffer_size[next_slot] = 0;
84

  
80 85
  write_buffer[next_slot] = (char *)malloc(sizeof(char) * WRITE_BUFFER_SIZE);
81

  
82 86
  if (!(write_buffer[next_slot])) {
83 87
    free(read_buffer[next_slot]);
84 88
    return ERROR_ALLOCATING_MEMORY;
85 89
  }
86

  
87 90
  write_buffer_size[next_slot] = 0;
88 91

  
89 92
  next_available_slot++;
......
105 108

  
106 109
  int client_file_descriptor = client_file_descriptor_array[pool_index];
107 110

  
111
	//clear this client from all lists of file descriptors
108 112
  if (FD_ISSET(client_file_descriptor, &ready_set)) {
109 113
    FD_CLR(client_file_descriptor, &ready_set);
110 114
  }
......
115 119
    FD_CLR(client_file_descriptor, &write_set);
116 120
  }
117 121

  
122
	//free up the resources this client used
118 123
  free(read_buffer[pool_index]);
119 124
  free(write_buffer[pool_index]);
125

  
126
	//shift the other clients down
120 127
  for (int j = pool_index; j < next_available_slot - 1; j++) {
121 128
    client_file_descriptor_array[pool_index] = client_file_descriptor_array[pool_index+1];
122 129
    read_buffer[pool_index] = read_buffer[pool_index+1];
......
127 134
  next_available_slot--;
128 135
  int temp_max_file_descriptor = 0;
129 136

  
137
	//figure out the newest max file descriptor
130 138
  for (int j = 0; j < next_available_slot; j++) {
131 139
    if (client_file_descriptor_array[j] > temp_max_file_descriptor)
132 140
      temp_max_file_descriptor = client_file_descriptor_array[j];
......
154 162
  for (i = 0; i < next_available_slot; i++) {
155 163
    int client_file_descriptor = client_file_descriptor_array[i];
156 164

  
165
		//check to see if this client is ready to be read from
157 166
    if (FD_ISSET(client_file_descriptor, &read_set)) {
158 167
      if (read_data(i, client_file_descriptor) == DECREMENT_INDEX_COUNTER) {
159
	i--;
160
	continue;
168
				i--;
169
				continue;
161 170
      }
162 171
    }
163 172

  
173
		//check to see if this client is ready to write to
164 174
    if (FD_ISSET(client_file_descriptor, &write_set)) {
165 175
      write_data(i, client_file_descriptor);
166 176
    }
......
243 253
  if (max_file_descriptor < listen_socket)
244 254
    max_file_descriptor = listen_socket;
245 255

  
256
	//call select.  select sees if any file descriptor in the read set is ready to be read and modifies the read set.  
257
	// It sees if any file descriptor in the write set is ready to be written to and modifies the write set.
246 258
  number_clients_ready = select(max_file_descriptor+1, &(read_set), &(write_set), NULL, &select_timeout);
247 259

  
248 260
  if (number_clients_ready < 0) {
......
252 264
  return 0;
253 265
}
254 266

  
267
/**
268
 * @return 1 if the socket is ready to be read, 0 otherwise
269
 */
255 270
int ConnectionPool::is_socket_ready_to_read(int socket) {
256 271
  return FD_ISSET(socket, &read_set);
257 272
}
258 273

  
274
/**
275
 * @return the number of clients that are ready
276
 */ 
259 277
int ConnectionPool::get_number_clients_ready() {
260 278
  return number_clients_ready;
261 279
}
262 280

  
263 281
/**
264
*/
282
 * @brief Reads data from a particular client and checks to see if it contains a command and parses that command 
283
 *   or buffers the data assuming the rest of the command will be sent later
284
 *
285
 * @param pool_index The index in the connection pool of the client to read from
286
 * @param client_file_descriptor The file descriptor of the client to read from
287
 *
288
 * @return 0 on success, negative error code on error
289
 */
265 290
int ConnectionPool::read_data(int pool_index, int client_file_descriptor) {
266 291
  char temporary_buffer[READ_BUFFER_SIZE];
267 292
  char temporary_command_buffer[READ_BUFFER_SIZE+1];
......
269 294
  int length;
270 295
  int command_length;
271 296

  
297
	//read data that the client is trying to send us
272 298
  num_bytes_read = read(client_file_descriptor, temporary_buffer, READ_BUFFER_SIZE);
273 299

  
300
	//check to see if the client disconnected
274 301
  if (num_bytes_read == 0 || (num_bytes_read == -1 && errno == ECONNRESET)) {
275 302
    remove_client(pool_index);
276 303
    return DECREMENT_INDEX_COUNTER;
277 304
  }
278 305

  
306
	
279 307
  while (num_bytes_read > 0) {
280 308
    length = num_bytes_read;
281 309

  
310
		//make sure this new data won't overflow the read buffer
282 311
    if (length + read_buffer_size[pool_index] > READ_BUFFER_SIZE) {
283 312
      length = READ_BUFFER_SIZE - read_buffer_size[pool_index];
284 313
    }
285 314

  
315
		//put the newly read data into the read buffer for this client
286 316
    memcpy(read_buffer[pool_index]+read_buffer_size[pool_index], temporary_buffer, length);
287 317
    read_buffer_size[pool_index] += length;
288 318
    num_bytes_read -= length;
......
291 321
      memmove(temporary_buffer, temporary_buffer+length, READ_BUFFER_SIZE - length);
292 322
    }
293 323

  
294
    //printf("read_data: Read buffer is %s\n", read_buffer[pool_index]);
295

  
296 324
    char* newline_position;
297 325

  
298 326
    while ((newline_position = strstr(read_buffer[pool_index], "\n"))) {
299

  
300
      //if no newline if found in the entire readbuffer (when its full),
301
      //toss out the command
327
      //if no newline is found in the entire readbuffer (when its full),
328
      // toss out the command
302 329
      // because either the command being given is too long or someone is trying
303 330
      // to do something bad to the server
304 331
      //TODO: this is from before all this code was put in the loop.  reconsider
......
348 375
  return 0;
349 376
}
350 377

  
378
/**
379
 * @brief This function takes data out of the write buffer for a client and tries to actually send it to the client
380
 *
381
 * @param pool_index The index in the connection pool of the client to write to
382
 * @param client_file_descriptor The file descriptor to write out on
383
 *
384
 * @return 0 on success, negative error code on failure
385
 */
351 386
int ConnectionPool::write_data(int pool_index, int client_file_descriptor) {
352 387
  if (write_buffer_size[pool_index] == 0) {
353 388
    return 0;

Also available in: Unified diff