File Coverage

blib/lib/IO/Framed/Write.pm
Criterion Covered Total %
statement 49 61 80.3
branch 9 12 75.0
condition 4 8 50.0
subroutine 14 16 87.5
pod 0 8 0.0
total 76 105 72.3


line stmt bran cond sub pod time code
1             package IO::Framed::Write;
2              
3 4     4   1773 use strict;
  4         10  
  4         117  
4 4     4   21 use warnings;
  4         6  
  4         103  
5              
6 4     4   428 use IO::Framed::X ();
  4         18  
  4         2814  
7              
8             sub new {
9 2     2 0 2285 my ( $class, $out_fh ) = @_;
10              
11 2         9 my $self = {
12             _out_fh => $out_fh,
13             _writer => \&_write_now,
14             };
15              
16 2         10 return bless $self, $class;
17             }
18              
19 0     0 0 0 sub get_write_fh { return $_[0]->{'_out_fh'} }
20              
21             sub disable_write_queue {
22 3 50 33 3 0 14 if ( $_[0]->{'_write_queue'} && @{ $_[0]->{'_write_queue'} } ) {
  0         0  
23 0         0 die 'Refuse to disable non-empty write queue!';
24             }
25              
26 3         7 $_[0]->{'_writer'} = \&_write_now;
27 3         15 return $_[0];
28             }
29              
30             sub enable_write_queue {
31 2   50 2 0 19 $_[0]->{'_write_queue'} ||= [];
32 2         7 $_[0]->{'_writer'} = \&_enqueue_write;
33 2         6 return $_[0];
34             }
35              
36             sub write {
37 65542     65542 0 131287 $_[0]->{'_writer'}->(@_);
38             }
39              
40             #======================================================================
41             #blocking
42             #======================================================================
43              
44             sub _write_now {
45 65539     65539   212035 local $!;
46              
47 65539 100       195378 $_[0]->can('WRITE')->( $_[0]->{'_out_fh'}, $_[1] ) or do {
48 1         42 die IO::Framed::X->create('WriteError', $!);
49             };
50              
51 65538 50       844721 $_[2]->() if $_[2];
52              
53 65538         236777 return;
54             }
55              
56             #======================================================================
57             #non-blocking
58             #======================================================================
59              
60             sub _enqueue_write {
61 3     3   6 my $self = shift;
62              
63 3         5 push @{ $self->{'_write_queue'} }, \@_;
  3         10  
64              
65 3         9 return;
66             }
67              
68             #----------------------------------------------------------------------
69              
70             sub flush_write_queue {
71 4098     4098 0 201532 my ($self) = @_;
72              
73 4098         10167 while ( my $qi = $self->{'_write_queue'}[0] ) {
74 4098 100       7592 return 0 if !$self->_write_now_then_callback( @$qi );
75              
76 3         6 shift @{ $self->{'_write_queue'} };
  3         16  
77             }
78              
79 3         12 return 1;
80             }
81              
82             sub get_write_queue_count {
83 5     5 0 598 my ($self) = @_;
84              
85 5         10 return 0 + @{ $self->{'_write_queue'} };
  5         22  
86             }
87              
88             sub forget_write_queue {
89 0     0 0 0 my ($self) = @_;
90              
91 0         0 my $count = @{ $self->{'_write_queue'} };
  0         0  
92              
93 0         0 @{ $self->{'_write_queue'} } = ();
  0         0  
94              
95 0         0 return $count;
96             }
97              
98             sub WRITE {
99 2     2   1017 require IO::SigGuard;
100 2         1598 *WRITE = *IO::SigGuard::syswrite;
101 2         12 goto &WRITE;
102             }
103              
104             #----------------------------------------------------------------------
105              
106             sub _write_now_then_callback {
107 4098     4098   11392 local $!;
108              
109 4098   66     14621 my $wrote = $_[0]->can('WRITE')->( $_[0]->{'_out_fh'}, $_[1] ) || do {
110 1     1   455 if ($! && !$!{'EAGAIN'} && !$!{'EWOULDBLOCK'}) {
  1         1420  
  1         9  
111             die IO::Framed::X->create('WriteError', $!);
112             }
113              
114             return undef;
115             };
116              
117 3 50       886 if ($wrote == length $_[1]) {
118 3         8 $_[0]->{'_write_queue_partial'} = 0;
119 3 100       11 $_[2]->() if $_[2];
120 3         16 return 1;
121             }
122              
123             #Trim the bytes that we did send.
124 0         0 substr( $_[1], 0, $wrote ) = q<>;
125              
126             #This seems useful to track … ??
127 0         0 $_[0]->{'_write_queue_partial'} = 1;
128              
129 0         0 return 0;
130             }
131              
132             1;