LEFT | RIGHT |
(no file at all) | |
1 // Copyright 2010 The Go Authors. All rights reserved. | 1 // Copyright 2010 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 /* | 5 /* |
6 The netchan package implements type-safe networked channels: | 6 The netchan package implements type-safe networked channels: |
7 it allows the two ends of a channel to appear on different | 7 it allows the two ends of a channel to appear on different |
8 computers connected by a network. It does this by transporting | 8 computers connected by a network. It does this by transporting |
9 data sent to a channel on one machine so it can be recovered | 9 data sent to a channel on one machine so it can be recovered |
10 by a receive of a channel of the same type on the other. | 10 by a receive of a channel of the same type on the other. |
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
336 // positive and Sync takes longer than that to complete, an error is | 336 // positive and Sync takes longer than that to complete, an error is |
337 // returned. | 337 // returned. |
338 func (exp *Exporter) Sync(timeout int64) os.Error { | 338 func (exp *Exporter) Sync(timeout int64) os.Error { |
339 // This wrapper function is here so the method's comment will appear in
godoc. | 339 // This wrapper function is here so the method's comment will appear in
godoc. |
340 return exp.clientSet.sync(timeout) | 340 return exp.clientSet.sync(timeout) |
341 } | 341 } |
342 | 342 |
343 func checkChan(chT interface{}, dir Dir) (reflect.Value, os.Error) { | 343 func checkChan(chT interface{}, dir Dir) (reflect.Value, os.Error) { |
344 chanType := reflect.TypeOf(chT) | 344 chanType := reflect.TypeOf(chT) |
345 if chanType.Kind() != reflect.Chan { | 345 if chanType.Kind() != reflect.Chan { |
346 » » return reflect.Value{}, os.ErrorString("not a channel") | 346 » » return reflect.Value{}, os.NewError("not a channel") |
347 } | 347 } |
348 if dir != Send && dir != Recv { | 348 if dir != Send && dir != Recv { |
349 » » return reflect.Value{}, os.ErrorString("unknown channel directio
n") | 349 » » return reflect.Value{}, os.NewError("unknown channel direction") |
350 } | 350 } |
351 switch chanType.ChanDir() { | 351 switch chanType.ChanDir() { |
352 case reflect.BothDir: | 352 case reflect.BothDir: |
353 case reflect.SendDir: | 353 case reflect.SendDir: |
354 if dir != Recv { | 354 if dir != Recv { |
355 » » » return reflect.Value{}, os.ErrorString("to import/export
with Send, must provide <-chan") | 355 » » » return reflect.Value{}, os.NewError("to import/export wi
th Send, must provide <-chan") |
356 } | 356 } |
357 case reflect.RecvDir: | 357 case reflect.RecvDir: |
358 if dir != Send { | 358 if dir != Send { |
359 » » » return reflect.Value{}, os.ErrorString("to import/export
with Recv, must provide chan<-") | 359 » » » return reflect.Value{}, os.NewError("to import/export wi
th Recv, must provide chan<-") |
360 } | 360 } |
361 } | 361 } |
362 return reflect.ValueOf(chT), nil | 362 return reflect.ValueOf(chT), nil |
363 } | 363 } |
364 | 364 |
365 // Export exports a channel of a given type and specified direction. The | 365 // Export exports a channel of a given type and specified direction. The |
366 // channel to be exported is provided in the call and may be of arbitrary | 366 // channel to be exported is provided in the call and may be of arbitrary |
367 // channel type. | 367 // channel type. |
368 // Despite the literal signature, the effective signature is | 368 // Despite the literal signature, the effective signature is |
369 // Export(name string, chT chan T, dir Dir) | 369 // Export(name string, chT chan T, dir Dir) |
370 func (exp *Exporter) Export(name string, chT interface{}, dir Dir) os.Error { | 370 func (exp *Exporter) Export(name string, chT interface{}, dir Dir) os.Error { |
371 ch, err := checkChan(chT, dir) | 371 ch, err := checkChan(chT, dir) |
372 if err != nil { | 372 if err != nil { |
373 return err | 373 return err |
374 } | 374 } |
375 exp.mu.Lock() | 375 exp.mu.Lock() |
376 defer exp.mu.Unlock() | 376 defer exp.mu.Unlock() |
377 _, present := exp.names[name] | 377 _, present := exp.names[name] |
378 if present { | 378 if present { |
379 » » return os.ErrorString("channel name already being exported:" + n
ame) | 379 » » return os.NewError("channel name already being exported:" + name
) |
380 } | 380 } |
381 exp.names[name] = &chanDir{ch, dir} | 381 exp.names[name] = &chanDir{ch, dir} |
382 return nil | 382 return nil |
383 } | 383 } |
384 | 384 |
385 // Hangup disassociates the named channel from the Exporter and closes | 385 // Hangup disassociates the named channel from the Exporter and closes |
386 // the channel. Messages in flight for the channel may be dropped. | 386 // the channel. Messages in flight for the channel may be dropped. |
387 func (exp *Exporter) Hangup(name string) os.Error { | 387 func (exp *Exporter) Hangup(name string) os.Error { |
388 exp.mu.Lock() | 388 exp.mu.Lock() |
389 chDir, ok := exp.names[name] | 389 chDir, ok := exp.names[name] |
390 if ok { | 390 if ok { |
391 exp.names[name] = nil, false | 391 exp.names[name] = nil, false |
392 } | 392 } |
393 // TODO drop all instances of channel from client sets | 393 // TODO drop all instances of channel from client sets |
394 exp.mu.Unlock() | 394 exp.mu.Unlock() |
395 if !ok { | 395 if !ok { |
396 » » return os.ErrorString("netchan export: hangup: no such channel:
" + name) | 396 » » return os.NewError("netchan export: hangup: no such channel: " +
name) |
397 } | 397 } |
398 chDir.ch.Close() | 398 chDir.ch.Close() |
399 return nil | 399 return nil |
400 } | 400 } |
LEFT | RIGHT |