⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sessiondata.pm

📁 1. 记录每个帖子的访问人情况
💻 PM
字号:
# ======================================================================## Copyright (C) 2000 Lincoln D. Stein# Slightly modified by Paul Kulchenko to work on multiple platforms## ======================================================================package IO::SessionData;use strict;use Carp;use IO::SessionSet;use vars '$VERSION';$VERSION = 1.01;use constant BUFSIZE => 3000;BEGIN {  my @names = qw(EWOULDBLOCK EAGAIN EINPROGRESS);  my %WOULDBLOCK =     (eval {require Errno} ? map {Errno->can($_)->() => 1} grep {Errno->can($_)} @names : ()),    (eval {require POSIX} ? map {POSIX->can($_)->() => 1} grep {POSIX->can($_)} @names : ());  sub WOULDBLOCK { $WOULDBLOCK{$_[0]+0} }}# Class method: new()# Create a new IO::SessionData object.  Intended to be called from within# IO::SessionSet, not directly.sub new {  my $pack = shift;  my ($sset,$handle,$writeonly) = @_;  # make the handle nonblocking  $handle->blocking(0);  my $self = bless {                outbuffer   => '',                sset        => $sset,                handle      => $handle,                write_limit => BUFSIZE,                writeonly   => $writeonly,                choker      => undef,                choked      => 0,               },$pack;  $self->readable(1) unless $writeonly;  return $self;}# Object method: handle()# Return the IO::Handle object corresponding to this IO::SessionDatasub handle   { return shift->{handle}   }# Object method: sessions()# Return the IO::SessionSet controlling this object.sub sessions { return shift->{sset} }# Object method: pending()# returns number of bytes pending in the out buffersub pending { return length shift->{outbuffer} }# Object method: write_limit([$bufsize])# Get or set the limit on the size of the write buffer.# Write buffer will grow to this size plus whatever extra you write to it.sub write_limit {   my $self = shift;  return defined $_[0] ? $self->{write_limit} = $_[0]                        : $self->{write_limit};}# set a callback to be called when the contents of the write buffer becomes larger# than the set limit.sub set_choke {  my $self = shift;  return defined $_[0] ? $self->{choker} = $_[0]                        : $self->{choker};}# Object method: write($scalar)# $obj->write([$data]) -- append data to buffer and try to write to handle# Returns number of bytes written, or 0E0 (zero but true) if data queued but not# written. On other errors, returns undef.sub write {  my $self = shift;  return unless my $handle = $self->handle; # no handle  return unless defined $self->{outbuffer}; # no buffer for queued data  $self->{outbuffer} .= $_[0] if defined $_[0];  my $rc;  if ($self->pending) { # data in the out buffer to write    local $SIG{PIPE}='IGNORE';    $rc = syswrite($handle,$self->{outbuffer});    # able to write, so truncate out buffer apropriately    if ($rc) {      substr($self->{outbuffer},0,$rc) = '';    } elsif (WOULDBLOCK($!)) {  # this is OK      $rc = '0E0';    } else { # some sort of write error, such as a PIPE error      return $self->bail_out($!);    }  } else {    $rc = '0E0';   # nothing to do, but no error either  }    $self->adjust_state;  # Result code is the number of bytes successfully transmitted  return $rc;}# Object method: read($scalar,$length [,$offset])# Just like sysread(), but returns the number of bytes read on success,# 0EO ("0 but true") if the read would block, and undef on EOF and other failures.sub read {  my $self = shift;  return unless my $handle = $self->handle;  my $rc = sysread($handle,$_[0],$_[1],$_[2]||0);  return $rc if defined $rc;  return '0E0' if WOULDBLOCK($!);  return;}# Object method: close()# Close the session and remove it from the monitored list.sub close {  my $self = shift;  unless ($self->pending) {    $self->sessions->delete($self);    close($self->handle);  } else {    $self->readable(0);    $self->{closing}++;  # delayed close    }}# Object method: adjust_state()# Called periodically from within write() to control the# status of the handle on the IO::SessionSet's IO::Select setssub adjust_state {  my $self = shift;  # make writable if there's anything in the out buffer  $self->writable($self->pending > 0);  # make readable if there's no write limit, or the amount in the out  # buffer is less than the write limit.  $self->choke($self->write_limit <= $self->pending) if $self->write_limit;  # Try to close down the session if it is flagged  # as in the closing state.  $self->close if $self->{closing};}# choke gets called when the contents of the write buffer are larger# than the limit.  The default action is to inactivate the session for further# reading until the situation is cleared.sub choke {  my $self = shift;  my $do_choke = shift;  return if $self->{choked} == $do_choke;  # no change in state  if (ref $self->set_choke eq 'CODE') {    $self->set_choke->($self,$do_choke);  } else {    $self->readable(!$do_choke);  }  $self->{choked} = $do_choke;}# Object method: readable($flag)# Flag the associated IO::SessionSet that we want to do reading on the handle.sub readable {  my $self = shift;  my $is_active = shift;  return if $self->{writeonly};  $self->sessions->activate($self,'read',$is_active);}# Object method: writable($flag)# Flag the associated IO::SessionSet that we want to do writing on the handle.sub writable {  my $self = shift;  my $is_active = shift;  $self->sessions->activate($self,'write',$is_active);}# Object method: bail_out([$errcode])# Called when an error is encountered during writing (such as a PIPE).# Default behavior is to flush all buffered outgoing data and to close# the handle.sub bail_out {  my $self = shift;  my $errcode = shift;           # save errorno  delete $self->{outbuffer};     # drop buffered data  $self->close;  $! = $errcode;                 # restore errno  return;}1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -