<commit_before>// Copyright 2014 Dmitry "Divius" Tantsur <<EMAIL>>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//

//! KRPC DHT service as described in
//! [BEP 0005](http://www.bittorrent.org/beps/bep_0005.html).

use std::io::IoResult;
use std::sync;

use super::super::base;
use super::super::knodetable;

use super::udpwrapper;


/// Generic implementation of basic KRPC DHT on which BitTorrent DHT is based.
///
/// No peer retrival is supported: just finding and pinging nodes.
///
/// Usually you will be creating it as:
/// ```
/// let service = dht::bt::KRpcService::new_default(this_node);
/// ```
pub struct KRpcService<TNodeTable: base::GenericNodeTable,
                       TSocket: udpwrapper::GenericSocketWrapper> {
    this_node: base::Node,
    node_table: sync::Arc<sync::RWLock<TNodeTable>>,
    socket: TSocket,
    // this is for tests only, proper cancelling will follow later
    active: sync::Arc<sync::RWLock<bool>>,
}

/// Default kind of KRpc service.
pub type DefaultKRpcService = KRpcService<knodetable::KNodeTable, udpwrapper::UdpSocketWrapper>;


// This can't be derived, compiler is confused because of Arc.
impl<TNodeTable: base::GenericNodeTable,
     TSocket: udpwrapper::GenericSocketWrapper>
Clone for KRpcService<TNodeTable, TSocket> {
    fn clone(&self) -> KRpcService<TNodeTable, TSocket> {
        KRpcService {
            this_node: self.this_node.clone(),
            node_table: self.node_table.clone(),
            socket: self.socket.clone(),
            active: self.active.clone(),
        }
    }
}

fn handle_incoming<TNodeTable: base::GenericNodeTable,
                   TSocket: udpwrapper::GenericSocketWrapper>
                   (service: KRpcService<TNodeTable, TSocket>) {
    while *service.active.read() {}
    // TODO(divius): implement
}

impl KRpcService<knodetable::KNodeTable, udpwrapper::UdpSocketWrapper> {
    /// New service with default node table.
    pub fn new_default(this_node: base::Node) -> IoResult<DefaultKRpcService> {
        let node_table = knodetable::KNodeTable::new(this_node.id.clone());
        let socket = try!(udpwrapper::UdpSocketWrapper::new(&this_node));
        KRpcService::new(this_node, node_table, socket)
    }
}

impl<TNodeTable: base::GenericNodeTable,
     TSocket: udpwrapper::GenericSocketWrapper>
KRpcService<TNodeTable, TSocket> {
    /// New service with given node table and socket.
    pub fn new(this_node: base::Node, node_table: TNodeTable, socket: TSocket)
            -> IoResult<KRpcService<TNodeTable, TSocket>> {
        let self_ = KRpcService {
            this_node: this_node,
            node_table: sync::Arc::new(sync::RWLock::new(node_table)),
            socket: socket,
            active: sync::Arc::new(sync::RWLock::new(true)),
        };

        let self_clone = self_.clone();
        spawn(move || handle_incoming(self_clone));

        Ok(self_)
    }

    /// Get lock guarding access to a node table.
    pub fn node_table_lock(&self) -> &sync::RWLock<TNodeTable> {
        self.node_table.deref()
    }

    /// Get reference to a socket wrapper.
    ///
    /// Clone it if you want to get mutable copy.
    pub fn socket_ref(&self) -> &TSocket {
        &self.socket
    }<commit_msg>Use Thread::spawn instead of deprecated task::spawn<commit_after>// Copyright 2014 Dmitry "Divius" Tantsur <<EMAIL>>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//

//! KRPC DHT service as described in
//! [BEP 0005](http://www.bittorrent.org/beps/bep_0005.html).

use std::io::IoResult;
use std::sync;
use std::thread;

use super::super::base;
use super::super::knodetable;

use super::udpwrapper;


/// Generic implementation of basic KRPC DHT on which BitTorrent DHT is based.
///
/// No peer retrival is supported: just finding and pinging nodes.
///
/// Usually you will be creating it as:
/// ```
/// let service = dht::bt::KRpcService::new_default(this_node);
/// ```
pub struct KRpcService<TNodeTable: base::GenericNodeTable,
                       TSocket: udpwrapper::GenericSocketWrapper> {
    this_node: base::Node,
    node_table: sync::Arc<sync::RWLock<TNodeTable>>,
    socket: TSocket,
    // this is for tests only, proper cancelling will follow later
    active: sync::Arc<sync::RWLock<bool>>,
}

/// Default kind of KRpc service.
pub type DefaultKRpcService = KRpcService<knodetable::KNodeTable, udpwrapper::UdpSocketWrapper>;


// This can't be derived, compiler is confused because of Arc.
impl<TNodeTable: base::GenericNodeTable,
     TSocket: udpwrapper::GenericSocketWrapper>
Clone for KRpcService<TNodeTable, TSocket> {
    fn clone(&self) -> KRpcService<TNodeTable, TSocket> {
        KRpcService {
            this_node: self.this_node.clone(),
            node_table: self.node_table.clone(),
            socket: self.socket.clone(),
            active: self.active.clone(),
        }
    }
}

fn handle_incoming<TNodeTable: base::GenericNodeTable,
                   TSocket: udpwrapper::GenericSocketWrapper>
                   (service: KRpcService<TNodeTable, TSocket>) {
    while *service.active.read() {}
    // TODO(divius): implement
}

impl KRpcService<knodetable::KNodeTable, udpwrapper::UdpSocketWrapper> {
    /// New service with default node table.
    pub fn new_default(this_node: base::Node) -> IoResult<DefaultKRpcService> {
        let node_table = knodetable::KNodeTable::new(this_node.id.clone());
        let socket = try!(udpwrapper::UdpSocketWrapper::new(&this_node));
        KRpcService::new(this_node, node_table, socket)
    }
}

impl<TNodeTable: base::GenericNodeTable,
     TSocket: udpwrapper::GenericSocketWrapper>
KRpcService<TNodeTable, TSocket> {
    /// New service with given node table and socket.
    pub fn new(this_node: base::Node, node_table: TNodeTable, socket: TSocket)
            -> IoResult<KRpcService<TNodeTable, TSocket>> {
        let self_ = KRpcService {
            this_node: this_node,
            node_table: sync::Arc::new(sync::RWLock::new(node_table)),
            socket: socket,
            active: sync::Arc::new(sync::RWLock::new(true)),
        };

        let self_clone = self_.clone();
        thread::Thread::spawn(move || handle_incoming(self_clone)).detach();

        Ok(self_)
    }

    /// Get lock guarding access to a node table.
    pub fn node_table_lock(&self) -> &sync::RWLock<TNodeTable> {
        self.node_table.deref()
    }

    /// Get reference to a socket wrapper.
    ///
    /// Clone it if you want to get mutable copy.
    pub fn socket_ref(&self) -> &TSocket {
        &self.socket
    }
{'fraction_non_alphanumeric': 0.13055791560464458, 'fraction_numerical': 0.004531294250920419, 'mean_word_length': 3.1867219917012446, 'pattern_counts': {'":': 0, '<': 47, '<?xml version=': 0, '>': 57, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5781602', 'n_tokens_mistral': 2239, 'n_tokens_neox': 2157, 'n_words': 537}